tecnualng 21.0.12 → 21.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,9 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, ChangeDetectionStrategy, ViewEncapsulation, Component, model, forwardRef, signal, computed, HostListener, viewChild, TemplateRef, contentChildren, effect, Injectable, createComponent, Input, Directive, output, ContentChildren } from '@angular/core';
3
- import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
2
+ import { input, ChangeDetectionStrategy, ViewEncapsulation, Component, model, forwardRef, inject, ElementRef, Renderer2, signal, computed, effect, HostListener, Directive, contentChild, viewChild, TemplateRef, contentChildren, Injectable, createComponent, Input, output, ContentChildren, ViewContainerRef, booleanAttribute } from '@angular/core';
3
+ import * as i1$2 from '@angular/forms';
4
+ import { FormsModule, NG_VALUE_ACCESSOR, NgControl } from '@angular/forms';
4
5
  import * as i1 from '@angular/common';
5
6
  import { CommonModule } from '@angular/common';
6
- import { trigger, transition, style, animate } from '@angular/animations';
7
7
  import * as i1$1 from '@angular/router';
8
8
  import { RouterModule } from '@angular/router';
9
9
 
@@ -33,7 +33,7 @@ class TngButton {
33
33
  button.appendChild(circle);
34
34
  }
35
35
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngButton, deps: [], target: i0.ɵɵFactoryTarget.Component });
36
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.0", type: TngButton, isStandalone: true, selector: "button[tngButton], a[tngButton]", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, soft: { classPropertyName: "soft", publicName: "soft", isSignal: true, isRequired: false, transformFunction: null }, ripple: { classPropertyName: "ripple", publicName: "ripple", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, iconPosition: { classPropertyName: "iconPosition", publicName: "iconPosition", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "createRipple($event)" }, properties: { "class.tng-button--primary": "variant() === \"primary\"", "class.tng-button--secondary": "variant() === \"secondary\"", "class.tng-button--success": "variant() === \"success\"", "class.tng-button--warning": "variant() === \"warning\"", "class.tng-button--error": "variant() === \"error\"", "class.tng-button--rounded": "rounded()", "class.tng-button--soft": "soft()" }, classAttribute: "tng-button" }, exportAs: ["tngButton"], ngImport: i0, template: "<span class=\"tng-button__label\">\n @if (icon() && iconPosition() === 'left') {\n <i [class]=\"icon()\" class=\"tng-button__icon tng-button__icon--left\"></i>\n }\n <ng-content></ng-content>\n @if (icon() && iconPosition() === 'right') {\n <i [class]=\"icon()\" class=\"tng-button__icon tng-button__icon--right\"></i>\n }\n</span>\n\n", styles: [".tng-button{position:relative;display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;min-width:64px;height:32px;border:none;outline:none;line-height:inherit;appearance:none;-webkit-appearance:none;overflow:hidden;vertical-align:middle;background:transparent;color:var(--tng-text);padding:0 16px;font-family:inherit;font-size:.875rem;font-weight:500;letter-spacing:.02857em;border-radius:4px;transition:background-color .25s cubic-bezier(.4,0,.2,1),box-shadow .25s cubic-bezier(.4,0,.2,1),border-radius .25s cubic-bezier(.4,0,.2,1),transform .1s ease-in-out}.tng-button::-moz-focus-inner{padding:0;border:0}.tng-button:active{outline:none;transform:scale(.98)}.tng-button:hover{cursor:pointer}.tng-button:disabled{cursor:default;pointer-events:none;opacity:.5}.tng-button[hidden]{display:none}.tng-button .mdc-button__label{position:relative;z-index:1;display:inline-flex;align-items:center;gap:8px}.tng-button .tng-button__icon--left{margin-right:4px}.tng-button .tng-button__icon--right{margin-left:4px}.tng-button--rounded{border-radius:24px}.tng-button--soft{box-shadow:0 2px 4px -1px #0000001a,0 4px 5px #00000012,0 1px 10px #0000000f}.tng-button--soft:hover{box-shadow:0 5px 5px -3px #0000001a,0 8px 10px 1px #00000012,0 3px 14px 2px #0000000f;transform:translateY(-1px)}.tng-button--primary{background:var(--tng-primary);color:var(--tng-primary-contrast)}.tng-button--primary:hover{background:color-mix(in srgb,var(--tng-primary),white 10%)}.tng-button--secondary{background:var(--tng-secondary);color:var(--tng-secondary-contrast)}.tng-button--secondary:hover{background:color-mix(in srgb,var(--tng-secondary),white 10%)}.tng-button--success{background:var(--tng-success);color:#fff}.tng-button--success:hover{background:color-mix(in srgb,var(--tng-success),white 10%)}.tng-button--warning{background:var(--tng-warning);color:#fff}.tng-button--warning:hover{background:color-mix(in srgb,var(--tng-warning),white 10%)}.tng-button--error{background:var(--tng-error);color:#fff}.tng-button--error:hover{background:color-mix(in srgb,var(--tng-error),white 10%)}span.tng-ripple{position:absolute;border-radius:50%;transform:scale(0);animation:ripple .6s linear;background-color:#ffffff4d;pointer-events:none}@keyframes ripple{to{transform:scale(4);opacity:0}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
36
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.0", type: TngButton, isStandalone: true, selector: "button[tngButton], a[tngButton]", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, soft: { classPropertyName: "soft", publicName: "soft", isSignal: true, isRequired: false, transformFunction: null }, ripple: { classPropertyName: "ripple", publicName: "ripple", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, iconPosition: { classPropertyName: "iconPosition", publicName: "iconPosition", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "createRipple($event)" }, properties: { "class.tng-button--primary": "variant() === \"primary\"", "class.tng-button--secondary": "variant() === \"secondary\"", "class.tng-button--success": "variant() === \"success\"", "class.tng-button--warning": "variant() === \"warning\"", "class.tng-button--error": "variant() === \"error\"", "class.tng-button--rounded": "rounded()", "class.tng-button--soft": "soft()" }, classAttribute: "tng-button" }, exportAs: ["tngButton"], ngImport: i0, template: "<span class=\"tng-button__label\">\n @if (icon() && iconPosition() === 'left') {\n <i [class]=\"icon()\" class=\"tng-button__icon tng-button__icon--left\"></i>\n }\n <ng-content></ng-content>\n @if (icon() && iconPosition() === 'right') {\n <i [class]=\"icon()\" class=\"tng-button__icon tng-button__icon--right\"></i>\n }\n</span>\n\n", styles: [".tng-button{position:relative;display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;min-width:64px;height:32px;border:none;outline:none;line-height:inherit;appearance:none;-webkit-appearance:none;overflow:hidden;vertical-align:middle;background:transparent;color:var(--tng-text);padding:0 16px;font-family:inherit;font-size:.875rem;font-weight:500;letter-spacing:.02857em;border-radius:4px;transition:background-color .25s cubic-bezier(.4,0,.2,1),box-shadow .25s cubic-bezier(.4,0,.2,1),border-radius .25s cubic-bezier(.4,0,.2,1),transform .1s ease-in-out}.tng-button::-moz-focus-inner{padding:0;border:0}.tng-button:active{outline:none;transform:scale(.98)}.tng-button:hover{cursor:pointer}.tng-button:disabled{cursor:default;pointer-events:none;opacity:.5}.tng-button[hidden]{display:none}.tng-button .mdc-button__label{position:relative;z-index:1;display:inline-flex;align-items:center;gap:8px}.tng-button .tng-button__icon--left{margin-right:4px}.tng-button .tng-button__icon--right{margin-left:4px}.tng-button--rounded{border-radius:24px}.tng-button--soft{box-shadow:0 2px 4px -1px #0000001a,0 4px 5px #00000012,0 1px 10px #0000000f}.tng-button--soft:hover{box-shadow:0 5px 5px -3px #0000001a,0 8px 10px 1px #00000012,0 3px 14px 2px #0000000f;transform:translateY(-1px)}.tng-button--primary{background:var(--tng-primary);color:var(--tng-primary-contrast)}.tng-button--primary:hover{background:color-mix(in srgb,var(--tng-primary-hover, --tng-primary),white 50%)}.tng-button--secondary{background:var(--tng-secondary);color:var(--tng-secondary-contrast)}.tng-button--secondary:hover{background:color-mix(in srgb,var(--tng-secondary-hover, --tng-secondary),white 50%)}.tng-button--success{background:var(--tng-success);color:#fff}.tng-button--success:hover{background:color-mix(in srgb,var(--tng-success),white 50%)}.tng-button--warning{background:var(--tng-warning);color:#fff}.tng-button--warning:hover{background:color-mix(in srgb,var(--tng-warning),white 50%)}.tng-button--error{background:var(--tng-error);color:#fff}.tng-button--error:hover{background:color-mix(in srgb,var(--tng-error),white 10%)}span.tng-ripple{position:absolute;border-radius:50%;transform:scale(0);animation:ripple .6s linear;background-color:#ffffff4d;pointer-events:none}@keyframes ripple{to{transform:scale(4);opacity:0}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
37
37
  }
38
38
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngButton, decorators: [{
39
39
  type: Component,
@@ -47,7 +47,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
47
47
  '[class.tng-button--rounded]': 'rounded()',
48
48
  '[class.tng-button--soft]': 'soft()',
49
49
  '(click)': 'createRipple($event)',
50
- }, exportAs: 'tngButton', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<span class=\"tng-button__label\">\n @if (icon() && iconPosition() === 'left') {\n <i [class]=\"icon()\" class=\"tng-button__icon tng-button__icon--left\"></i>\n }\n <ng-content></ng-content>\n @if (icon() && iconPosition() === 'right') {\n <i [class]=\"icon()\" class=\"tng-button__icon tng-button__icon--right\"></i>\n }\n</span>\n\n", styles: [".tng-button{position:relative;display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;min-width:64px;height:32px;border:none;outline:none;line-height:inherit;appearance:none;-webkit-appearance:none;overflow:hidden;vertical-align:middle;background:transparent;color:var(--tng-text);padding:0 16px;font-family:inherit;font-size:.875rem;font-weight:500;letter-spacing:.02857em;border-radius:4px;transition:background-color .25s cubic-bezier(.4,0,.2,1),box-shadow .25s cubic-bezier(.4,0,.2,1),border-radius .25s cubic-bezier(.4,0,.2,1),transform .1s ease-in-out}.tng-button::-moz-focus-inner{padding:0;border:0}.tng-button:active{outline:none;transform:scale(.98)}.tng-button:hover{cursor:pointer}.tng-button:disabled{cursor:default;pointer-events:none;opacity:.5}.tng-button[hidden]{display:none}.tng-button .mdc-button__label{position:relative;z-index:1;display:inline-flex;align-items:center;gap:8px}.tng-button .tng-button__icon--left{margin-right:4px}.tng-button .tng-button__icon--right{margin-left:4px}.tng-button--rounded{border-radius:24px}.tng-button--soft{box-shadow:0 2px 4px -1px #0000001a,0 4px 5px #00000012,0 1px 10px #0000000f}.tng-button--soft:hover{box-shadow:0 5px 5px -3px #0000001a,0 8px 10px 1px #00000012,0 3px 14px 2px #0000000f;transform:translateY(-1px)}.tng-button--primary{background:var(--tng-primary);color:var(--tng-primary-contrast)}.tng-button--primary:hover{background:color-mix(in srgb,var(--tng-primary),white 10%)}.tng-button--secondary{background:var(--tng-secondary);color:var(--tng-secondary-contrast)}.tng-button--secondary:hover{background:color-mix(in srgb,var(--tng-secondary),white 10%)}.tng-button--success{background:var(--tng-success);color:#fff}.tng-button--success:hover{background:color-mix(in srgb,var(--tng-success),white 10%)}.tng-button--warning{background:var(--tng-warning);color:#fff}.tng-button--warning:hover{background:color-mix(in srgb,var(--tng-warning),white 10%)}.tng-button--error{background:var(--tng-error);color:#fff}.tng-button--error:hover{background:color-mix(in srgb,var(--tng-error),white 10%)}span.tng-ripple{position:absolute;border-radius:50%;transform:scale(0);animation:ripple .6s linear;background-color:#ffffff4d;pointer-events:none}@keyframes ripple{to{transform:scale(4);opacity:0}}\n"] }]
50
+ }, exportAs: 'tngButton', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<span class=\"tng-button__label\">\n @if (icon() && iconPosition() === 'left') {\n <i [class]=\"icon()\" class=\"tng-button__icon tng-button__icon--left\"></i>\n }\n <ng-content></ng-content>\n @if (icon() && iconPosition() === 'right') {\n <i [class]=\"icon()\" class=\"tng-button__icon tng-button__icon--right\"></i>\n }\n</span>\n\n", styles: [".tng-button{position:relative;display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;min-width:64px;height:32px;border:none;outline:none;line-height:inherit;appearance:none;-webkit-appearance:none;overflow:hidden;vertical-align:middle;background:transparent;color:var(--tng-text);padding:0 16px;font-family:inherit;font-size:.875rem;font-weight:500;letter-spacing:.02857em;border-radius:4px;transition:background-color .25s cubic-bezier(.4,0,.2,1),box-shadow .25s cubic-bezier(.4,0,.2,1),border-radius .25s cubic-bezier(.4,0,.2,1),transform .1s ease-in-out}.tng-button::-moz-focus-inner{padding:0;border:0}.tng-button:active{outline:none;transform:scale(.98)}.tng-button:hover{cursor:pointer}.tng-button:disabled{cursor:default;pointer-events:none;opacity:.5}.tng-button[hidden]{display:none}.tng-button .mdc-button__label{position:relative;z-index:1;display:inline-flex;align-items:center;gap:8px}.tng-button .tng-button__icon--left{margin-right:4px}.tng-button .tng-button__icon--right{margin-left:4px}.tng-button--rounded{border-radius:24px}.tng-button--soft{box-shadow:0 2px 4px -1px #0000001a,0 4px 5px #00000012,0 1px 10px #0000000f}.tng-button--soft:hover{box-shadow:0 5px 5px -3px #0000001a,0 8px 10px 1px #00000012,0 3px 14px 2px #0000000f;transform:translateY(-1px)}.tng-button--primary{background:var(--tng-primary);color:var(--tng-primary-contrast)}.tng-button--primary:hover{background:color-mix(in srgb,var(--tng-primary-hover, --tng-primary),white 50%)}.tng-button--secondary{background:var(--tng-secondary);color:var(--tng-secondary-contrast)}.tng-button--secondary:hover{background:color-mix(in srgb,var(--tng-secondary-hover, --tng-secondary),white 50%)}.tng-button--success{background:var(--tng-success);color:#fff}.tng-button--success:hover{background:color-mix(in srgb,var(--tng-success),white 50%)}.tng-button--warning{background:var(--tng-warning);color:#fff}.tng-button--warning:hover{background:color-mix(in srgb,var(--tng-warning),white 50%)}.tng-button--error{background:var(--tng-error);color:#fff}.tng-button--error:hover{background:color-mix(in srgb,var(--tng-error),white 10%)}span.tng-ripple{position:absolute;border-radius:50%;transform:scale(0);animation:ripple .6s linear;background-color:#ffffff4d;pointer-events:none}@keyframes ripple{to{transform:scale(4);opacity:0}}\n"] }]
51
51
  }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: false }] }], soft: [{ type: i0.Input, args: [{ isSignal: true, alias: "soft", required: false }] }], ripple: [{ type: i0.Input, args: [{ isSignal: true, alias: "ripple", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], iconPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconPosition", required: false }] }] } });
52
52
 
53
53
  class TngCardComponent {
@@ -59,7 +59,7 @@ class TngCardComponent {
59
59
  image = input(null, ...(ngDevMode ? [{ debugName: "image" }] : []));
60
60
  imageAlt = input('Card image', ...(ngDevMode ? [{ debugName: "imageAlt" }] : []));
61
61
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
62
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.0", type: TngCardComponent, isStandalone: true, selector: "tng-card", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, elevated: { classPropertyName: "elevated", publicName: "elevated", isSignal: true, isRequired: false, transformFunction: null }, outlined: { classPropertyName: "outlined", publicName: "outlined", isSignal: true, isRequired: false, transformFunction: null }, image: { classPropertyName: "image", publicName: "image", isSignal: true, isRequired: false, transformFunction: null }, imageAlt: { classPropertyName: "imageAlt", publicName: "imageAlt", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.tng-card--primary": "variant() === \"primary\"", "class.tng-card--secondary": "variant() === \"secondary\"", "class.tng-card--success": "variant() === \"success\"", "class.tng-card--warning": "variant() === \"warning\"", "class.tng-card--error": "variant() === \"error\"", "class.tng-card--elevated": "elevated()", "class.tng-card--outlined": "outlined()" }, classAttribute: "tng-card" }, ngImport: i0, template: "<div class=\"tng-card__container\">\n @if (image()) {\n <div class=\"tng-card__image\">\n <img [src]=\"image()\" [alt]=\"imageAlt()\" />\n </div>\n }\n\n @if (title() || subtitle()) {\n <div class=\"tng-card__header\">\n <ng-content select=\"[card-header]\"></ng-content>\n \n @if (!title() && !subtitle()) {\n <!-- Header projection only -->\n } @else {\n <div class=\"tng-card__header-text\">\n @if (title()) {\n <h3 class=\"tng-card__title\">{{ title() }}</h3>\n }\n @if (subtitle()) {\n <p class=\"tng-card__subtitle\">{{ subtitle() }}</p>\n }\n </div>\n }\n </div>\n }\n\n <div class=\"tng-card__content\">\n <ng-content></ng-content>\n </div>\n\n <div class=\"tng-card__footer\">\n <ng-content select=\"[card-footer]\"></ng-content>\n </div>\n</div>\n", styles: [".tng-card{display:block;position:relative;background-color:#fff;border-radius:8px;overflow:hidden;transition:box-shadow .3s cubic-bezier(.4,0,.2,1),transform .2s cubic-bezier(.4,0,.2,1)}.tng-card__container{display:flex;flex-direction:column;height:100%}.tng-card__image{width:100%;overflow:hidden}.tng-card__image img{width:100%;height:auto;display:block;object-fit:cover}.tng-card__header{padding:16px 20px;border-bottom:1px solid rgba(0,0,0,.08)}.tng-card__header-text{display:flex;flex-direction:column;gap:4px}.tng-card__title{margin:0;font-size:1.25rem;font-weight:500;color:var(--tng-text, #333);line-height:1.4}.tng-card__subtitle{margin:0;font-size:.875rem;color:var(--tng-text-secondary, #666);line-height:1.5}.tng-card__content{padding:20px;flex:1;color:var(--tng-text, #333)}.tng-card__footer{padding:12px 20px;border-top:1px solid rgba(0,0,0,.08)}.tng-card__footer:empty{display:none}.tng-card--elevated{box-shadow:0 2px 4px -1px #0000001a,0 4px 5px #00000012,0 1px 10px #0000000f}.tng-card--elevated:hover{box-shadow:0 5px 5px -3px #0000001a,0 8px 10px 1px #00000012,0 3px 14px 2px #0000000f;transform:translateY(-2px)}.tng-card--outlined{border:1px solid rgba(0,0,0,.12);box-shadow:none}.tng-card--outlined:hover{border-color:#0000003d}.tng-card--primary .tng-card__header{background:var(--tng-primary);color:var(--tng-primary-contrast);border-bottom-color:#ffffff1f}.tng-card--primary .tng-card__title,.tng-card--primary .tng-card__subtitle{color:inherit}.tng-card--secondary .tng-card__header{background:var(--tng-secondary);color:var(--tng-secondary-contrast);border-bottom-color:#ffffff1f}.tng-card--secondary .tng-card__title,.tng-card--secondary .tng-card__subtitle{color:inherit}.tng-card--success .tng-card__header{background:var(--tng-success);color:#fff;border-bottom-color:#ffffff1f}.tng-card--success .tng-card__title,.tng-card--success .tng-card__subtitle{color:inherit}.tng-card--warning .tng-card__header{background:var(--tng-warning);color:#fff;border-bottom-color:#ffffff1f}.tng-card--warning .tng-card__title,.tng-card--warning .tng-card__subtitle{color:inherit}.tng-card--error .tng-card__header{background:var(--tng-error);color:#fff;border-bottom-color:#ffffff1f}.tng-card--error .tng-card__title,.tng-card--error .tng-card__subtitle{color:inherit}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
62
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.0", type: TngCardComponent, isStandalone: true, selector: "tng-card", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, elevated: { classPropertyName: "elevated", publicName: "elevated", isSignal: true, isRequired: false, transformFunction: null }, outlined: { classPropertyName: "outlined", publicName: "outlined", isSignal: true, isRequired: false, transformFunction: null }, image: { classPropertyName: "image", publicName: "image", isSignal: true, isRequired: false, transformFunction: null }, imageAlt: { classPropertyName: "imageAlt", publicName: "imageAlt", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.tng-card--primary": "variant() === \"primary\"", "class.tng-card--secondary": "variant() === \"secondary\"", "class.tng-card--success": "variant() === \"success\"", "class.tng-card--warning": "variant() === \"warning\"", "class.tng-card--error": "variant() === \"error\"", "class.tng-card--elevated": "elevated()", "class.tng-card--outlined": "outlined()" }, classAttribute: "tng-card" }, ngImport: i0, template: "<div class=\"tng-card__container\">\n @if (image()) {\n <div class=\"tng-card__image\">\n <img [src]=\"image()\" [alt]=\"imageAlt()\" />\n </div>\n }\n\n @if (title() || subtitle()) {\n <div class=\"tng-card__header\">\n <ng-content select=\"[card-header]\"></ng-content>\n \n @if (!title() && !subtitle()) {\n <!-- Header projection only -->\n } @else {\n <div class=\"tng-card__header-text\">\n @if (title()) {\n <h3 class=\"tng-card__title\">{{ title() }}</h3>\n }\n @if (subtitle()) {\n <p class=\"tng-card__subtitle\">{{ subtitle() }}</p>\n }\n </div>\n }\n </div>\n }\n\n <div class=\"tng-card__content\">\n <ng-content></ng-content>\n </div>\n\n <div class=\"tng-card__footer\">\n <ng-content select=\"[card-footer]\"></ng-content>\n </div>\n</div>\n", styles: [".tng-card{display:block;position:relative;background-color:var(--tng-surface);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid var(--tng-border);border-radius:8px;overflow:hidden;transition:box-shadow .3s cubic-bezier(.4,0,.2,1),transform .2s cubic-bezier(.4,0,.2,1)}.tng-card__container{display:flex;flex-direction:column;height:100%}.tng-card__image{width:100%;overflow:hidden}.tng-card__image img{width:100%;height:auto;display:block;object-fit:cover}.tng-card__header{padding:16px 20px;border-bottom:1px solid var(--tng-border)}.tng-card__header-text{display:flex;flex-direction:column;gap:4px}.tng-card__title{margin:0;font-size:1.25rem;font-weight:500;color:var(--tng-text, #333);line-height:1.4}.tng-card__subtitle{margin:0;font-size:.875rem;color:var(--tng-text-secondary, #666);line-height:1.5}.tng-card__content{padding:20px;flex:1;color:var(--tng-text, #333)}.tng-card__footer{padding:12px 20px;border-top:1px solid var(--tng-border)}.tng-card__footer:empty{display:none}.tng-card--elevated{box-shadow:var(--tng-shadow-md)}.tng-card--elevated:hover{box-shadow:0 8px 16px #0000004d;transform:translateY(-2px)}.tng-card--outlined{border:1px solid var(--tng-border);box-shadow:none}.tng-card--outlined:hover{border-color:var(--tng-primary)}.tng-card--primary .tng-card__header{background:var(--tng-primary);color:var(--tng-primary-contrast);border-bottom-color:#ffffff1f}.tng-card--primary .tng-card__title,.tng-card--primary .tng-card__subtitle{color:inherit}.tng-card--secondary .tng-card__header{background:var(--tng-secondary);color:var(--tng-secondary-contrast);border-bottom-color:#ffffff1f}.tng-card--secondary .tng-card__title,.tng-card--secondary .tng-card__subtitle{color:inherit}.tng-card--success .tng-card__header{background:var(--tng-success);color:#fff;border-bottom-color:#ffffff1f}.tng-card--success .tng-card__title,.tng-card--success .tng-card__subtitle{color:inherit}.tng-card--warning .tng-card__header{background:var(--tng-warning);color:#fff;border-bottom-color:#ffffff1f}.tng-card--warning .tng-card__title,.tng-card--warning .tng-card__subtitle{color:inherit}.tng-card--error .tng-card__header{background:var(--tng-error);color:#fff;border-bottom-color:#ffffff1f}.tng-card--error .tng-card__title,.tng-card--error .tng-card__subtitle{color:inherit}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
63
63
  }
64
64
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngCardComponent, decorators: [{
65
65
  type: Component,
@@ -72,7 +72,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
72
72
  '[class.tng-card--error]': 'variant() === "error"',
73
73
  '[class.tng-card--elevated]': 'elevated()',
74
74
  '[class.tng-card--outlined]': 'outlined()',
75
- }, template: "<div class=\"tng-card__container\">\n @if (image()) {\n <div class=\"tng-card__image\">\n <img [src]=\"image()\" [alt]=\"imageAlt()\" />\n </div>\n }\n\n @if (title() || subtitle()) {\n <div class=\"tng-card__header\">\n <ng-content select=\"[card-header]\"></ng-content>\n \n @if (!title() && !subtitle()) {\n <!-- Header projection only -->\n } @else {\n <div class=\"tng-card__header-text\">\n @if (title()) {\n <h3 class=\"tng-card__title\">{{ title() }}</h3>\n }\n @if (subtitle()) {\n <p class=\"tng-card__subtitle\">{{ subtitle() }}</p>\n }\n </div>\n }\n </div>\n }\n\n <div class=\"tng-card__content\">\n <ng-content></ng-content>\n </div>\n\n <div class=\"tng-card__footer\">\n <ng-content select=\"[card-footer]\"></ng-content>\n </div>\n</div>\n", styles: [".tng-card{display:block;position:relative;background-color:#fff;border-radius:8px;overflow:hidden;transition:box-shadow .3s cubic-bezier(.4,0,.2,1),transform .2s cubic-bezier(.4,0,.2,1)}.tng-card__container{display:flex;flex-direction:column;height:100%}.tng-card__image{width:100%;overflow:hidden}.tng-card__image img{width:100%;height:auto;display:block;object-fit:cover}.tng-card__header{padding:16px 20px;border-bottom:1px solid rgba(0,0,0,.08)}.tng-card__header-text{display:flex;flex-direction:column;gap:4px}.tng-card__title{margin:0;font-size:1.25rem;font-weight:500;color:var(--tng-text, #333);line-height:1.4}.tng-card__subtitle{margin:0;font-size:.875rem;color:var(--tng-text-secondary, #666);line-height:1.5}.tng-card__content{padding:20px;flex:1;color:var(--tng-text, #333)}.tng-card__footer{padding:12px 20px;border-top:1px solid rgba(0,0,0,.08)}.tng-card__footer:empty{display:none}.tng-card--elevated{box-shadow:0 2px 4px -1px #0000001a,0 4px 5px #00000012,0 1px 10px #0000000f}.tng-card--elevated:hover{box-shadow:0 5px 5px -3px #0000001a,0 8px 10px 1px #00000012,0 3px 14px 2px #0000000f;transform:translateY(-2px)}.tng-card--outlined{border:1px solid rgba(0,0,0,.12);box-shadow:none}.tng-card--outlined:hover{border-color:#0000003d}.tng-card--primary .tng-card__header{background:var(--tng-primary);color:var(--tng-primary-contrast);border-bottom-color:#ffffff1f}.tng-card--primary .tng-card__title,.tng-card--primary .tng-card__subtitle{color:inherit}.tng-card--secondary .tng-card__header{background:var(--tng-secondary);color:var(--tng-secondary-contrast);border-bottom-color:#ffffff1f}.tng-card--secondary .tng-card__title,.tng-card--secondary .tng-card__subtitle{color:inherit}.tng-card--success .tng-card__header{background:var(--tng-success);color:#fff;border-bottom-color:#ffffff1f}.tng-card--success .tng-card__title,.tng-card--success .tng-card__subtitle{color:inherit}.tng-card--warning .tng-card__header{background:var(--tng-warning);color:#fff;border-bottom-color:#ffffff1f}.tng-card--warning .tng-card__title,.tng-card--warning .tng-card__subtitle{color:inherit}.tng-card--error .tng-card__header{background:var(--tng-error);color:#fff;border-bottom-color:#ffffff1f}.tng-card--error .tng-card__title,.tng-card--error .tng-card__subtitle{color:inherit}\n"] }]
75
+ }, template: "<div class=\"tng-card__container\">\n @if (image()) {\n <div class=\"tng-card__image\">\n <img [src]=\"image()\" [alt]=\"imageAlt()\" />\n </div>\n }\n\n @if (title() || subtitle()) {\n <div class=\"tng-card__header\">\n <ng-content select=\"[card-header]\"></ng-content>\n \n @if (!title() && !subtitle()) {\n <!-- Header projection only -->\n } @else {\n <div class=\"tng-card__header-text\">\n @if (title()) {\n <h3 class=\"tng-card__title\">{{ title() }}</h3>\n }\n @if (subtitle()) {\n <p class=\"tng-card__subtitle\">{{ subtitle() }}</p>\n }\n </div>\n }\n </div>\n }\n\n <div class=\"tng-card__content\">\n <ng-content></ng-content>\n </div>\n\n <div class=\"tng-card__footer\">\n <ng-content select=\"[card-footer]\"></ng-content>\n </div>\n</div>\n", styles: [".tng-card{display:block;position:relative;background-color:var(--tng-surface);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid var(--tng-border);border-radius:8px;overflow:hidden;transition:box-shadow .3s cubic-bezier(.4,0,.2,1),transform .2s cubic-bezier(.4,0,.2,1)}.tng-card__container{display:flex;flex-direction:column;height:100%}.tng-card__image{width:100%;overflow:hidden}.tng-card__image img{width:100%;height:auto;display:block;object-fit:cover}.tng-card__header{padding:16px 20px;border-bottom:1px solid var(--tng-border)}.tng-card__header-text{display:flex;flex-direction:column;gap:4px}.tng-card__title{margin:0;font-size:1.25rem;font-weight:500;color:var(--tng-text, #333);line-height:1.4}.tng-card__subtitle{margin:0;font-size:.875rem;color:var(--tng-text-secondary, #666);line-height:1.5}.tng-card__content{padding:20px;flex:1;color:var(--tng-text, #333)}.tng-card__footer{padding:12px 20px;border-top:1px solid var(--tng-border)}.tng-card__footer:empty{display:none}.tng-card--elevated{box-shadow:var(--tng-shadow-md)}.tng-card--elevated:hover{box-shadow:0 8px 16px #0000004d;transform:translateY(-2px)}.tng-card--outlined{border:1px solid var(--tng-border);box-shadow:none}.tng-card--outlined:hover{border-color:var(--tng-primary)}.tng-card--primary .tng-card__header{background:var(--tng-primary);color:var(--tng-primary-contrast);border-bottom-color:#ffffff1f}.tng-card--primary .tng-card__title,.tng-card--primary .tng-card__subtitle{color:inherit}.tng-card--secondary .tng-card__header{background:var(--tng-secondary);color:var(--tng-secondary-contrast);border-bottom-color:#ffffff1f}.tng-card--secondary .tng-card__title,.tng-card--secondary .tng-card__subtitle{color:inherit}.tng-card--success .tng-card__header{background:var(--tng-success);color:#fff;border-bottom-color:#ffffff1f}.tng-card--success .tng-card__title,.tng-card--success .tng-card__subtitle{color:inherit}.tng-card--warning .tng-card__header{background:var(--tng-warning);color:#fff;border-bottom-color:#ffffff1f}.tng-card--warning .tng-card__title,.tng-card--warning .tng-card__subtitle{color:inherit}.tng-card--error .tng-card__header{background:var(--tng-error);color:#fff;border-bottom-color:#ffffff1f}.tng-card--error .tng-card__title,.tng-card--error .tng-card__subtitle{color:inherit}\n"] }]
76
76
  }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], elevated: [{ type: i0.Input, args: [{ isSignal: true, alias: "elevated", required: false }] }], outlined: [{ type: i0.Input, args: [{ isSignal: true, alias: "outlined", required: false }] }], image: [{ type: i0.Input, args: [{ isSignal: true, alias: "image", required: false }] }], imageAlt: [{ type: i0.Input, args: [{ isSignal: true, alias: "imageAlt", required: false }] }] } });
77
77
 
78
78
  class TecnualInputComponent {
@@ -120,7 +120,7 @@ class TecnualInputComponent {
120
120
  useExisting: forwardRef(() => TecnualInputComponent),
121
121
  multi: true
122
122
  }
123
- ], ngImport: i0, template: "<div class=\"tng-input-container\" [class.focused]=\"isFocused\" [class.has-value]=\"hasValue\" [class.disabled]=\"disabled()\">\n <fieldset class=\"tng-fieldset\" aria-hidden=\"true\">\n <legend class=\"tng-legend\"><span>{{ label() }}</span></legend>\n </fieldset>\n <label [for]=\"id()\" class=\"tng-label\">{{ label() }}</label>\n <input\n [id]=\"id()\"\n [type]=\"type()\"\n [placeholder]=\"isFocused ? placeholder() : ''\"\n [value]=\"value\"\n [disabled]=\"disabled()\"\n [required]=\"required()\"\n (input)=\"onInput($event)\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n class=\"tng-input-field\"\n />\n</div>\n", styles: [":host{display:block;margin-bottom:1.5rem;font-family:var(--tng-font-family, \"Inter\", sans-serif)}.tng-input-container{position:relative;border-radius:var(--tng-border-radius, 4px);padding:0 16px;height:48px;display:flex;align-items:center;cursor:text;border:none}.tng-input-container:hover .tng-fieldset{border-color:var(--tng-text-secondary, #757575)}.tng-input-container.focused .tng-fieldset{border-color:var(--tng-primary, #6200ee);border-width:2px}.tng-input-container.focused .tng-label{color:var(--tng-primary, #6200ee);transform:translateY(-24px) scale(.75)}.tng-input-container.focused .tng-legend{max-width:100%}.tng-input-container.has-value .tng-label{transform:translateY(-24px) scale(.75)}.tng-input-container.has-value .tng-legend{max-width:100%}.tng-input-container.disabled{opacity:.6;pointer-events:none}.tng-input-container.disabled .tng-fieldset{border-color:var(--tng-border, #e0e0e0);background-color:var(--tng-background, #fafafa)}.tng-fieldset{position:absolute;inset:0 0 5px;margin:0;padding:0 12px;border:1px solid var(--tng-border, #999);border-radius:var(--tng-border-radius, 4px);pointer-events:none;transition:border-color .2s ease,border-width .1s ease;z-index:0}.tng-legend{width:auto;max-width:0;height:11px;font-size:.75em;visibility:hidden;transition:max-width .1s cubic-bezier(.4,0,.2,1);white-space:nowrap;padding-inline:0px}.tng-legend span{padding:0 2px;visibility:visible;opacity:0}.tng-label{position:absolute;top:50%;left:16px;transform:translateY(-50%);color:var(--tng-text-secondary, #666);font-size:16px;font-weight:400;pointer-events:none;transform-origin:left top;transition:transform .2s cubic-bezier(.4,0,.2,1),color .2s ease;z-index:1}.tng-input-field{display:block;width:100%;border:none;background:none;padding:0;margin:0;font-size:16px;color:var(--tng-text, #333);outline:none;height:100%;line-height:normal;z-index:1}.tng-input-field::placeholder{color:transparent;transition:color .2s ease}.tng-input-field:focus::placeholder{color:#aaa}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }] });
123
+ ], ngImport: i0, template: "<div class=\"tng-input-container\" [class.focused]=\"isFocused\" [class.has-value]=\"hasValue\" [class.disabled]=\"disabled()\">\n <fieldset class=\"tng-fieldset\" aria-hidden=\"true\">\n <legend class=\"tng-legend\"><span>{{ label() }}</span></legend>\n </fieldset>\n <label [for]=\"id()\" class=\"tng-label\">{{ label() }}</label>\n <input\n [id]=\"id()\"\n [type]=\"type()\"\n [placeholder]=\"isFocused ? placeholder() : ''\"\n [value]=\"value\"\n [disabled]=\"disabled()\"\n [required]=\"required()\"\n (input)=\"onInput($event)\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n class=\"tng-input-field\"\n />\n</div>\n", styles: [":host{display:block;margin-bottom:1.5rem;font-family:var(--tng-font-family, \"Inter\", sans-serif)}.tng-input-container{position:relative;padding:0 16px;height:48px;display:flex;align-items:center;cursor:text;border:none}.tng-input-container:hover .tng-fieldset{border-color:var(--tng-text-secondary, #757575)}.tng-input-container.focused .tng-fieldset{border-color:var(--tng-primary, #6200ee);border-width:2px}.tng-input-container.focused .tng-label{color:var(--tng-primary, #6200ee);transform:translateY(-24px) scale(.75)}.tng-input-container.focused .tng-legend{max-width:100%}.tng-input-container.has-value .tng-label{transform:translateY(-24px) scale(.75)}.tng-input-container.has-value .tng-legend{max-width:100%}.tng-input-container.disabled{opacity:.6;pointer-events:none}.tng-input-container.disabled .tng-fieldset{border-color:var(--tng-border, #e0e0e0);background-color:var(--tng-background, #fafafa)}.tng-fieldset{position:absolute;inset:0 0 5px;margin:0;padding:0 12px;border:1px solid var(--tng-border, #999);border-radius:var(--tng-border-radius, 4px);background-color:var(--tng-surface);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);pointer-events:none;transition:border-color .2s ease,border-width .1s ease;z-index:0}.tng-legend{width:auto;max-width:0;height:11px;font-size:.75em;visibility:hidden;transition:max-width .1s cubic-bezier(.4,0,.2,1);white-space:nowrap;padding-inline:0px}.tng-legend span{padding:0 2px;visibility:visible;opacity:0}.tng-label{position:absolute;top:50%;left:16px;transform:translateY(-50%);color:var(--tng-text-secondary, #666);font-size:16px;font-weight:400;pointer-events:none;transform-origin:left top;transition:transform .2s cubic-bezier(.4,0,.2,1),color .2s ease;z-index:1}.tng-input-field{display:block;width:100%;border:none;background:none;padding:0;margin:0;font-size:16px;color:var(--tng-text, #333);outline:none;height:100%;line-height:normal;z-index:1}.tng-input-field::placeholder{color:transparent;transition:color .2s ease}.tng-input-field:focus::placeholder{color:#aaa}.tng-checkbox{appearance:none;-webkit-appearance:none;-moz-appearance:none;width:20px;height:20px;min-width:20px;min-height:20px;border:2px solid var(--tng-border, #999);border-radius:var(--tng-border-radius, 4px);background-color:var(--tng-surface, #ffffff);cursor:pointer;position:relative;transition:all .3s cubic-bezier(.4,0,.2,1);outline:none;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.tng-checkbox:hover:not(:disabled){border-color:var(--tng-primary, #00f2ff);box-shadow:0 0 0 4px #00f2ff1a}.tng-checkbox:focus{border-color:var(--tng-primary, #00f2ff);box-shadow:0 0 0 4px #00f2ff33}.tng-checkbox:checked{background-color:var(--tng-primary, #00f2ff);border-color:var(--tng-primary, #00f2ff)}.tng-checkbox:checked:before{content:\"\";position:absolute;width:5px;height:10px;border:solid var(--tng-primary-contrast, #000000);border-width:0 2px 2px 0;transform:rotate(45deg) scale(1);opacity:1;transition:all .2s cubic-bezier(.4,0,.2,1)}.tng-checkbox:not(:checked):before{content:\"\";position:absolute;width:5px;height:10px;border:solid var(--tng-primary-contrast, #000000);border-width:0 2px 2px 0;transform:rotate(45deg) scale(0);opacity:0;transition:all .2s cubic-bezier(.4,0,.2,1)}.tng-checkbox:disabled{opacity:.5;cursor:not-allowed;border-color:var(--tng-border, #e0e0e0);background-color:var(--tng-background, #fafafa)}.tng-checkbox:disabled:checked{background-color:var(--tng-text-secondary, #757575);border-color:var(--tng-text-secondary, #757575)}.tng-checkbox:active:not(:disabled){transform:scale(.95)}.tng-radio{appearance:none;-webkit-appearance:none;-moz-appearance:none;width:20px;height:20px;min-width:20px;min-height:20px;border:2px solid var(--tng-border, #999);border-radius:50%;background-color:var(--tng-surface, #ffffff);cursor:pointer;position:relative;transition:all .3s cubic-bezier(.4,0,.2,1);outline:none;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.tng-radio:hover:not(:disabled){border-color:var(--tng-primary, #00f2ff);box-shadow:0 0 0 4px #00f2ff1a}.tng-radio:focus{border-color:var(--tng-primary, #00f2ff);box-shadow:0 0 0 4px #00f2ff33}.tng-radio:checked{border-color:var(--tng-primary, #00f2ff);border-width:2px}.tng-radio:checked:before{content:\"\";position:absolute;width:10px;height:10px;border-radius:50%;background-color:var(--tng-primary, #00f2ff);transform:scale(1);opacity:1;transition:all .2s cubic-bezier(.4,0,.2,1)}.tng-radio:not(:checked):before{content:\"\";position:absolute;width:10px;height:10px;border-radius:50%;background-color:var(--tng-primary, #00f2ff);transform:scale(0);opacity:0;transition:all .2s cubic-bezier(.4,0,.2,1)}.tng-radio:disabled{opacity:.5;cursor:not-allowed;border-color:var(--tng-border, #e0e0e0);background-color:var(--tng-background, #fafafa)}.tng-radio:disabled:checked:before{background-color:var(--tng-text-secondary, #757575)}.tng-radio:active:not(:disabled){transform:scale(.95)}@keyframes ripple{0%{transform:scale(0);opacity:.5}to{transform:scale(2);opacity:0}}.tng-checkbox,.tng-radio{overflow:visible}.tng-checkbox:after,.tng-radio:after{content:\"\";position:absolute;width:100%;height:100%;border-radius:inherit;background-color:var(--tng-primary, #00f2ff);opacity:0;pointer-events:none}.tng-checkbox:active:not(:disabled):after,.tng-radio:active:not(:disabled):after{animation:ripple .6s ease-out}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }] });
124
124
  }
125
125
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TecnualInputComponent, decorators: [{
126
126
  type: Component,
@@ -130,9 +130,122 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
130
130
  useExisting: forwardRef(() => TecnualInputComponent),
131
131
  multi: true
132
132
  }
133
- ], template: "<div class=\"tng-input-container\" [class.focused]=\"isFocused\" [class.has-value]=\"hasValue\" [class.disabled]=\"disabled()\">\n <fieldset class=\"tng-fieldset\" aria-hidden=\"true\">\n <legend class=\"tng-legend\"><span>{{ label() }}</span></legend>\n </fieldset>\n <label [for]=\"id()\" class=\"tng-label\">{{ label() }}</label>\n <input\n [id]=\"id()\"\n [type]=\"type()\"\n [placeholder]=\"isFocused ? placeholder() : ''\"\n [value]=\"value\"\n [disabled]=\"disabled()\"\n [required]=\"required()\"\n (input)=\"onInput($event)\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n class=\"tng-input-field\"\n />\n</div>\n", styles: [":host{display:block;margin-bottom:1.5rem;font-family:var(--tng-font-family, \"Inter\", sans-serif)}.tng-input-container{position:relative;border-radius:var(--tng-border-radius, 4px);padding:0 16px;height:48px;display:flex;align-items:center;cursor:text;border:none}.tng-input-container:hover .tng-fieldset{border-color:var(--tng-text-secondary, #757575)}.tng-input-container.focused .tng-fieldset{border-color:var(--tng-primary, #6200ee);border-width:2px}.tng-input-container.focused .tng-label{color:var(--tng-primary, #6200ee);transform:translateY(-24px) scale(.75)}.tng-input-container.focused .tng-legend{max-width:100%}.tng-input-container.has-value .tng-label{transform:translateY(-24px) scale(.75)}.tng-input-container.has-value .tng-legend{max-width:100%}.tng-input-container.disabled{opacity:.6;pointer-events:none}.tng-input-container.disabled .tng-fieldset{border-color:var(--tng-border, #e0e0e0);background-color:var(--tng-background, #fafafa)}.tng-fieldset{position:absolute;inset:0 0 5px;margin:0;padding:0 12px;border:1px solid var(--tng-border, #999);border-radius:var(--tng-border-radius, 4px);pointer-events:none;transition:border-color .2s ease,border-width .1s ease;z-index:0}.tng-legend{width:auto;max-width:0;height:11px;font-size:.75em;visibility:hidden;transition:max-width .1s cubic-bezier(.4,0,.2,1);white-space:nowrap;padding-inline:0px}.tng-legend span{padding:0 2px;visibility:visible;opacity:0}.tng-label{position:absolute;top:50%;left:16px;transform:translateY(-50%);color:var(--tng-text-secondary, #666);font-size:16px;font-weight:400;pointer-events:none;transform-origin:left top;transition:transform .2s cubic-bezier(.4,0,.2,1),color .2s ease;z-index:1}.tng-input-field{display:block;width:100%;border:none;background:none;padding:0;margin:0;font-size:16px;color:var(--tng-text, #333);outline:none;height:100%;line-height:normal;z-index:1}.tng-input-field::placeholder{color:transparent;transition:color .2s ease}.tng-input-field:focus::placeholder{color:#aaa}\n"] }]
133
+ ], template: "<div class=\"tng-input-container\" [class.focused]=\"isFocused\" [class.has-value]=\"hasValue\" [class.disabled]=\"disabled()\">\n <fieldset class=\"tng-fieldset\" aria-hidden=\"true\">\n <legend class=\"tng-legend\"><span>{{ label() }}</span></legend>\n </fieldset>\n <label [for]=\"id()\" class=\"tng-label\">{{ label() }}</label>\n <input\n [id]=\"id()\"\n [type]=\"type()\"\n [placeholder]=\"isFocused ? placeholder() : ''\"\n [value]=\"value\"\n [disabled]=\"disabled()\"\n [required]=\"required()\"\n (input)=\"onInput($event)\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n class=\"tng-input-field\"\n />\n</div>\n", styles: [":host{display:block;margin-bottom:1.5rem;font-family:var(--tng-font-family, \"Inter\", sans-serif)}.tng-input-container{position:relative;padding:0 16px;height:48px;display:flex;align-items:center;cursor:text;border:none}.tng-input-container:hover .tng-fieldset{border-color:var(--tng-text-secondary, #757575)}.tng-input-container.focused .tng-fieldset{border-color:var(--tng-primary, #6200ee);border-width:2px}.tng-input-container.focused .tng-label{color:var(--tng-primary, #6200ee);transform:translateY(-24px) scale(.75)}.tng-input-container.focused .tng-legend{max-width:100%}.tng-input-container.has-value .tng-label{transform:translateY(-24px) scale(.75)}.tng-input-container.has-value .tng-legend{max-width:100%}.tng-input-container.disabled{opacity:.6;pointer-events:none}.tng-input-container.disabled .tng-fieldset{border-color:var(--tng-border, #e0e0e0);background-color:var(--tng-background, #fafafa)}.tng-fieldset{position:absolute;inset:0 0 5px;margin:0;padding:0 12px;border:1px solid var(--tng-border, #999);border-radius:var(--tng-border-radius, 4px);background-color:var(--tng-surface);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);pointer-events:none;transition:border-color .2s ease,border-width .1s ease;z-index:0}.tng-legend{width:auto;max-width:0;height:11px;font-size:.75em;visibility:hidden;transition:max-width .1s cubic-bezier(.4,0,.2,1);white-space:nowrap;padding-inline:0px}.tng-legend span{padding:0 2px;visibility:visible;opacity:0}.tng-label{position:absolute;top:50%;left:16px;transform:translateY(-50%);color:var(--tng-text-secondary, #666);font-size:16px;font-weight:400;pointer-events:none;transform-origin:left top;transition:transform .2s cubic-bezier(.4,0,.2,1),color .2s ease;z-index:1}.tng-input-field{display:block;width:100%;border:none;background:none;padding:0;margin:0;font-size:16px;color:var(--tng-text, #333);outline:none;height:100%;line-height:normal;z-index:1}.tng-input-field::placeholder{color:transparent;transition:color .2s ease}.tng-input-field:focus::placeholder{color:#aaa}.tng-checkbox{appearance:none;-webkit-appearance:none;-moz-appearance:none;width:20px;height:20px;min-width:20px;min-height:20px;border:2px solid var(--tng-border, #999);border-radius:var(--tng-border-radius, 4px);background-color:var(--tng-surface, #ffffff);cursor:pointer;position:relative;transition:all .3s cubic-bezier(.4,0,.2,1);outline:none;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.tng-checkbox:hover:not(:disabled){border-color:var(--tng-primary, #00f2ff);box-shadow:0 0 0 4px #00f2ff1a}.tng-checkbox:focus{border-color:var(--tng-primary, #00f2ff);box-shadow:0 0 0 4px #00f2ff33}.tng-checkbox:checked{background-color:var(--tng-primary, #00f2ff);border-color:var(--tng-primary, #00f2ff)}.tng-checkbox:checked:before{content:\"\";position:absolute;width:5px;height:10px;border:solid var(--tng-primary-contrast, #000000);border-width:0 2px 2px 0;transform:rotate(45deg) scale(1);opacity:1;transition:all .2s cubic-bezier(.4,0,.2,1)}.tng-checkbox:not(:checked):before{content:\"\";position:absolute;width:5px;height:10px;border:solid var(--tng-primary-contrast, #000000);border-width:0 2px 2px 0;transform:rotate(45deg) scale(0);opacity:0;transition:all .2s cubic-bezier(.4,0,.2,1)}.tng-checkbox:disabled{opacity:.5;cursor:not-allowed;border-color:var(--tng-border, #e0e0e0);background-color:var(--tng-background, #fafafa)}.tng-checkbox:disabled:checked{background-color:var(--tng-text-secondary, #757575);border-color:var(--tng-text-secondary, #757575)}.tng-checkbox:active:not(:disabled){transform:scale(.95)}.tng-radio{appearance:none;-webkit-appearance:none;-moz-appearance:none;width:20px;height:20px;min-width:20px;min-height:20px;border:2px solid var(--tng-border, #999);border-radius:50%;background-color:var(--tng-surface, #ffffff);cursor:pointer;position:relative;transition:all .3s cubic-bezier(.4,0,.2,1);outline:none;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle}.tng-radio:hover:not(:disabled){border-color:var(--tng-primary, #00f2ff);box-shadow:0 0 0 4px #00f2ff1a}.tng-radio:focus{border-color:var(--tng-primary, #00f2ff);box-shadow:0 0 0 4px #00f2ff33}.tng-radio:checked{border-color:var(--tng-primary, #00f2ff);border-width:2px}.tng-radio:checked:before{content:\"\";position:absolute;width:10px;height:10px;border-radius:50%;background-color:var(--tng-primary, #00f2ff);transform:scale(1);opacity:1;transition:all .2s cubic-bezier(.4,0,.2,1)}.tng-radio:not(:checked):before{content:\"\";position:absolute;width:10px;height:10px;border-radius:50%;background-color:var(--tng-primary, #00f2ff);transform:scale(0);opacity:0;transition:all .2s cubic-bezier(.4,0,.2,1)}.tng-radio:disabled{opacity:.5;cursor:not-allowed;border-color:var(--tng-border, #e0e0e0);background-color:var(--tng-background, #fafafa)}.tng-radio:disabled:checked:before{background-color:var(--tng-text-secondary, #757575)}.tng-radio:active:not(:disabled){transform:scale(.95)}@keyframes ripple{0%{transform:scale(0);opacity:.5}to{transform:scale(2);opacity:0}}.tng-checkbox,.tng-radio{overflow:visible}.tng-checkbox:after,.tng-radio:after{content:\"\";position:absolute;width:100%;height:100%;border-radius:inherit;background-color:var(--tng-primary, #00f2ff);opacity:0;pointer-events:none}.tng-checkbox:active:not(:disabled):after,.tng-radio:active:not(:disabled):after{animation:ripple .6s ease-out}\n"] }]
134
134
  }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }, { type: i0.Output, args: ["disabledChange"] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }] } });
135
135
 
136
+ class TngInputDirective {
137
+ el = inject((ElementRef));
138
+ renderer = inject(Renderer2);
139
+ ngControl = inject(NgControl, { optional: true, self: true });
140
+ // Inputs
141
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
142
+ placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
143
+ // State signals
144
+ focused = signal(false, ...(ngDevMode ? [{ debugName: "focused" }] : []));
145
+ checked = signal(false, ...(ngDevMode ? [{ debugName: "checked" }] : []));
146
+ _value = signal('', ...(ngDevMode ? [{ debugName: "_value" }] : []));
147
+ _inputType = signal('text', ...(ngDevMode ? [{ debugName: "_inputType" }] : []));
148
+ // Computed
149
+ hasValue = computed(() => {
150
+ const val = this._value();
151
+ return val !== null && val !== undefined && val !== '';
152
+ }, ...(ngDevMode ? [{ debugName: "hasValue" }] : []));
153
+ computedPlaceholder = computed(() => {
154
+ return this.focused() ? this.placeholder() : '';
155
+ }, ...(ngDevMode ? [{ debugName: "computedPlaceholder" }] : []));
156
+ isCheckbox = computed(() => this._inputType() === 'checkbox', ...(ngDevMode ? [{ debugName: "isCheckbox" }] : []));
157
+ isRadio = computed(() => this._inputType() === 'radio', ...(ngDevMode ? [{ debugName: "isRadio" }] : []));
158
+ isTextField = computed(() => !this.isCheckbox() && !this.isRadio(), ...(ngDevMode ? [{ debugName: "isTextField" }] : []));
159
+ constructor() {
160
+ // Initialize value on creation
161
+ effect(() => {
162
+ this.updateValue();
163
+ }, { allowSignalWrites: true });
164
+ // Detect input type after view init
165
+ effect(() => {
166
+ this.detectInputType();
167
+ }, { allowSignalWrites: true });
168
+ }
169
+ onFocus() {
170
+ this.focused.set(true);
171
+ }
172
+ onBlur() {
173
+ this.focused.set(false);
174
+ this.updateValue();
175
+ }
176
+ onInput() {
177
+ this.updateValue();
178
+ }
179
+ onChange() {
180
+ if (this.isCheckbox() || this.isRadio()) {
181
+ const element = this.el.nativeElement;
182
+ this.checked.set(element.checked);
183
+ }
184
+ }
185
+ ngAfterViewInit() {
186
+ this.detectInputType();
187
+ this.updateValue();
188
+ // For checkbox/radio, also update checked state
189
+ if (this.isCheckbox() || this.isRadio()) {
190
+ const element = this.el.nativeElement;
191
+ this.checked.set(element.checked);
192
+ }
193
+ }
194
+ detectInputType() {
195
+ const element = this.el.nativeElement;
196
+ if ('type' in element) {
197
+ this._inputType.set(element.type || 'text');
198
+ }
199
+ }
200
+ updateValue() {
201
+ this._value.set(this.el.nativeElement.value);
202
+ }
203
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngInputDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
204
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.0", type: TngInputDirective, isStandalone: true, selector: "input[tngInput], textarea[tngInput]", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "focus": "onFocus()", "blur": "onBlur()", "input": "onInput()", "change": "onChange()" }, properties: { "class.tng-input-field": "isTextField()", "class.tng-checkbox": "isCheckbox()", "class.tng-radio": "isRadio()", "disabled": "disabled()", "attr.placeholder": "computedPlaceholder()" } }, ngImport: i0 });
205
+ }
206
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngInputDirective, decorators: [{
207
+ type: Directive,
208
+ args: [{
209
+ selector: 'input[tngInput], textarea[tngInput]',
210
+ standalone: true,
211
+ host: {
212
+ '[class.tng-input-field]': 'isTextField()',
213
+ '[class.tng-checkbox]': 'isCheckbox()',
214
+ '[class.tng-radio]': 'isRadio()',
215
+ '[disabled]': 'disabled()',
216
+ '[attr.placeholder]': 'computedPlaceholder()'
217
+ }
218
+ }]
219
+ }], ctorParameters: () => [], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], onFocus: [{
220
+ type: HostListener,
221
+ args: ['focus']
222
+ }], onBlur: [{
223
+ type: HostListener,
224
+ args: ['blur']
225
+ }], onInput: [{
226
+ type: HostListener,
227
+ args: ['input']
228
+ }], onChange: [{
229
+ type: HostListener,
230
+ args: ['change']
231
+ }] } });
232
+
233
+ class TngFormFieldComponent {
234
+ label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
235
+ // Query for the input directive inside this component
236
+ inputDirective = contentChild(TngInputDirective, ...(ngDevMode ? [{ debugName: "inputDirective" }] : []));
237
+ // Computed states based on the input directive
238
+ isFocused = computed(() => this.inputDirective()?.focused() ?? false, ...(ngDevMode ? [{ debugName: "isFocused" }] : []));
239
+ hasValue = computed(() => this.inputDirective()?.hasValue() ?? false, ...(ngDevMode ? [{ debugName: "hasValue" }] : []));
240
+ isDisabled = computed(() => this.inputDirective()?.disabled() ?? false, ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
241
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngFormFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
242
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.0.0", type: TngFormFieldComponent, isStandalone: true, selector: "tng-form-field", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "inputDirective", first: true, predicate: TngInputDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"tng-input-container\" \n [class.focused]=\"isFocused()\" \n [class.has-value]=\"hasValue()\" \n [class.disabled]=\"isDisabled()\">\n <fieldset class=\"tng-fieldset\" aria-hidden=\"true\">\n <legend class=\"tng-legend\"><span>{{ label() }}</span></legend>\n </fieldset>\n <label class=\"tng-label\">{{ label() }}</label>\n <ng-content></ng-content>\n</div>\n", styles: [":host{display:block;margin-bottom:1.5rem;font-family:var(--tng-font-family, \"Inter\", sans-serif)}.tng-input-container{position:relative;border-radius:var(--tng-border-radius, 4px);padding:0 16px;min-height:48px;display:flex;align-items:center;cursor:text;border:none}.tng-input-container:hover .tng-fieldset{border-color:var(--tng-text-secondary, #757575)}.tng-input-container.focused .tng-fieldset{border-color:var(--tng-primary, #6200ee);border-width:2px}.tng-input-container.focused .tng-label{color:var(--tng-primary, #6200ee);transform:translateY(-24px) scale(.75)}.tng-input-container.focused .tng-legend{max-width:100%}.tng-input-container.has-value .tng-label{transform:translateY(-24px) scale(.75)}.tng-input-container.has-value .tng-legend{max-width:100%}.tng-input-container.disabled{opacity:.6;pointer-events:none}.tng-input-container.disabled .tng-fieldset{border-color:var(--tng-border, #e0e0e0);background-color:var(--tng-background, #fafafa)}.tng-fieldset{position:absolute;inset:0 0 5px;margin:0;padding:0 12px;border:1px solid var(--tng-border, #999);border-radius:var(--tng-border-radius, 4px);pointer-events:none;transition:border-color .2s ease,border-width .1s ease;z-index:0}.tng-legend{width:auto;max-width:0;height:11px;font-size:.75em;visibility:hidden;transition:max-width .1s cubic-bezier(.4,0,.2,1);white-space:nowrap;padding-inline:0px}.tng-legend span{padding:0 2px;visibility:visible;opacity:0}.tng-label{position:absolute;top:50%;left:16px;transform:translateY(-50%);color:var(--tng-text-secondary, #666);font-size:16px;font-weight:400;pointer-events:none;transform-origin:left top;transition:transform .2s cubic-bezier(.4,0,.2,1),color .2s ease;z-index:1}input.tng-input-field,textarea.tng-input-field{display:block;width:100%;border:none;background:none;padding:0;margin:0;font-size:16px;color:var(--tng-text, #333);outline:none;height:100%;min-height:48px;line-height:normal;z-index:1;font-family:inherit}input.tng-input-field::placeholder,textarea.tng-input-field::placeholder{color:transparent;transition:color .2s ease}input.tng-input-field:focus::placeholder,textarea.tng-input-field:focus::placeholder{color:#aaa}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], encapsulation: i0.ViewEncapsulation.None });
243
+ }
244
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngFormFieldComponent, decorators: [{
245
+ type: Component,
246
+ args: [{ selector: 'tng-form-field', standalone: true, imports: [CommonModule], encapsulation: ViewEncapsulation.None, template: "<div class=\"tng-input-container\" \n [class.focused]=\"isFocused()\" \n [class.has-value]=\"hasValue()\" \n [class.disabled]=\"isDisabled()\">\n <fieldset class=\"tng-fieldset\" aria-hidden=\"true\">\n <legend class=\"tng-legend\"><span>{{ label() }}</span></legend>\n </fieldset>\n <label class=\"tng-label\">{{ label() }}</label>\n <ng-content></ng-content>\n</div>\n", styles: [":host{display:block;margin-bottom:1.5rem;font-family:var(--tng-font-family, \"Inter\", sans-serif)}.tng-input-container{position:relative;border-radius:var(--tng-border-radius, 4px);padding:0 16px;min-height:48px;display:flex;align-items:center;cursor:text;border:none}.tng-input-container:hover .tng-fieldset{border-color:var(--tng-text-secondary, #757575)}.tng-input-container.focused .tng-fieldset{border-color:var(--tng-primary, #6200ee);border-width:2px}.tng-input-container.focused .tng-label{color:var(--tng-primary, #6200ee);transform:translateY(-24px) scale(.75)}.tng-input-container.focused .tng-legend{max-width:100%}.tng-input-container.has-value .tng-label{transform:translateY(-24px) scale(.75)}.tng-input-container.has-value .tng-legend{max-width:100%}.tng-input-container.disabled{opacity:.6;pointer-events:none}.tng-input-container.disabled .tng-fieldset{border-color:var(--tng-border, #e0e0e0);background-color:var(--tng-background, #fafafa)}.tng-fieldset{position:absolute;inset:0 0 5px;margin:0;padding:0 12px;border:1px solid var(--tng-border, #999);border-radius:var(--tng-border-radius, 4px);pointer-events:none;transition:border-color .2s ease,border-width .1s ease;z-index:0}.tng-legend{width:auto;max-width:0;height:11px;font-size:.75em;visibility:hidden;transition:max-width .1s cubic-bezier(.4,0,.2,1);white-space:nowrap;padding-inline:0px}.tng-legend span{padding:0 2px;visibility:visible;opacity:0}.tng-label{position:absolute;top:50%;left:16px;transform:translateY(-50%);color:var(--tng-text-secondary, #666);font-size:16px;font-weight:400;pointer-events:none;transform-origin:left top;transition:transform .2s cubic-bezier(.4,0,.2,1),color .2s ease;z-index:1}input.tng-input-field,textarea.tng-input-field{display:block;width:100%;border:none;background:none;padding:0;margin:0;font-size:16px;color:var(--tng-text, #333);outline:none;height:100%;min-height:48px;line-height:normal;z-index:1;font-family:inherit}input.tng-input-field::placeholder,textarea.tng-input-field::placeholder{color:transparent;transition:color .2s ease}input.tng-input-field:focus::placeholder,textarea.tng-input-field:focus::placeholder{color:#aaa}\n"] }]
247
+ }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], inputDirective: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TngInputDirective), { isSignal: true }] }] } });
248
+
136
249
  class TecnualDatepickerComponent {
137
250
  elementRef;
138
251
  label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
@@ -320,7 +433,7 @@ class TecnualDatepickerComponent {
320
433
  useExisting: forwardRef(() => TecnualDatepickerComponent),
321
434
  multi: true
322
435
  }
323
- ], ngImport: i0, template: "<div class=\"tng-datepicker-container\" [class.focused]=\"isOpen()\" [class.has-value]=\"formattedValue\" [class.disabled]=\"disabled()\">\n <!-- Trigger Field (Reusing Input Style) -->\n <div class=\"tng-input-trigger\" (click)=\"toggleCalendar()\">\n <fieldset class=\"tng-fieldset\" aria-hidden=\"true\">\n <legend class=\"tng-legend\"><span>{{ label() }}</span></legend>\n </fieldset>\n <label class=\"tng-label\">{{ label() }}</label>\n <div class=\"tng-input-display\">\n {{ formattedValue || (isOpen() ? placeholder() : '') }}\n </div>\n <span class=\"material-icons tng-icon\">calendar_today</span>\n </div>\n\n <!-- Calendar Popup -->\n @if (isOpen()) {\n <div class=\"tng-calendar-popup\">\n <div class=\"tng-calendar-header\">\n <button type=\"button\" class=\"nav-btn\" (click)=\"prevMonth($event)\">\n <span class=\"material-icons\">chevron_left</span>\n </button>\n <span class=\"current-month\">{{ currentMonthYear }}</span>\n <button type=\"button\" class=\"nav-btn\" (click)=\"nextMonth($event)\">\n <span class=\"material-icons\">chevron_right</span>\n </button>\n </div>\n\n <div class=\"tng-calendar-grid\">\n @for (day of daysOfWeek; track day) {\n <div class=\"day-name\">{{ day }}</div>\n }\n @for (date of calendarDays(); track date.getTime()) {\n <div\n class=\"day-cell\"\n [class.not-current-month]=\"!isCurrentMonth(date)\"\n [class.today]=\"isToday(date)\"\n [class.selected]=\"isSelected(date)\"\n [class.in-range]=\"isInRange(date)\"\n [class.range-start]=\"mode() === 'range' && isSameDay(date, rangeValue.start)\"\n [class.range-end]=\"mode() === 'range' && isSameDay(date, rangeValue.end)\"\n [class.disabled]=\"isDisabled(date)\"\n (click)=\"selectDate(date)\"\n >\n {{ date.getDate() }}\n </div>\n }\n </div>\n </div>\n }\n</div>\n", styles: [":host{display:block;margin-bottom:1.5rem;font-family:var(--tng-font-family, \"Inter\", sans-serif);position:relative}.tng-datepicker-container{position:relative}.tng-datepicker-container.disabled{opacity:.6;pointer-events:none}.tng-datepicker-container.disabled .tng-fieldset{border-color:var(--tng-border, #ccc);background-color:var(--tng-background, #f9f9f9)}.tng-input-trigger{position:relative;border-radius:var(--tng-border-radius, 4px);padding:0 16px;height:48px;display:flex;align-items:center;cursor:pointer}.tng-input-trigger:hover .tng-fieldset{border-color:color-mix(in srgb,var(--tng-border, #999),black 20%)}.tng-fieldset{position:absolute;inset:0 0 5px;margin:0;padding:0 12px;border:1px solid var(--tng-border, #999);border-radius:var(--tng-border-radius, 4px);pointer-events:none;transition:border-color .2s ease}.tng-legend{width:auto;max-width:0;height:11px;font-size:.75em;visibility:hidden;white-space:nowrap;padding-inline:0px}.tng-legend span{padding:0 2px;visibility:visible;opacity:0}.tng-label{position:absolute;top:50%;left:16px;transform:translateY(-50%);color:var(--tng-text-secondary, #666);font-size:16px;font-weight:400;pointer-events:none;transform-origin:left top;transition:transform .2s cubic-bezier(.4,0,.2,1),color .2s ease}.tng-input-display{flex:1;font-size:16px;color:var(--tng-text, #333);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center}.tng-icon{color:var(--tng-text-secondary, #666);font-size:20px;margin-left:8px}.tng-datepicker-container.focused .tng-fieldset,.tng-datepicker-container.has-value .tng-fieldset{border-color:var(--tng-primary, #6200ee);border-width:2px}.tng-datepicker-container.focused .tng-label,.tng-datepicker-container.has-value .tng-label{color:var(--tng-primary, #6200ee);transform:translateY(-24px) scale(.75)}.tng-datepicker-container.focused .tng-legend,.tng-datepicker-container.has-value .tng-legend{max-width:100%}.tng-datepicker-container.focused .tng-label{color:var(--tng-primary, #6200ee)}.tng-calendar-popup{position:absolute;top:100%;left:0;z-index:1000;margin-top:4px;background:var(--tng-surface, #fff);border-radius:8px;box-shadow:var(--tng-shadow-md, 0 4px 20px rgba(0, 0, 0, .15));padding:16px;width:300px;animation:fadeIn .2s ease;border:1px solid var(--tng-border, #eee)}@keyframes fadeIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.tng-calendar-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:16px}.tng-calendar-header .current-month{font-weight:600;font-size:16px;color:var(--tng-text, #333)}.tng-calendar-header .nav-btn{background:none;border:none;cursor:pointer;padding:4px;border-radius:50%;display:flex;align-items:center;justify-content:center;color:var(--tng-text-secondary, #666)}.tng-calendar-header .nav-btn:hover{background-color:var(--tng-background, #f5f5f5)}.tng-calendar-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;text-align:center}.day-name{font-size:12px;color:var(--tng-text-secondary, #666);font-weight:500;margin-bottom:8px}.day-cell{height:36px;display:flex;align-items:center;justify-content:center;font-size:14px;cursor:pointer;border-radius:50%;transition:all .2s ease;position:relative;color:var(--tng-text, #333)}.day-cell:hover:not(.disabled):not(.selected):not(.range-start):not(.range-end){background-color:var(--tng-background, #f5f5f5)}.day-cell.not-current-month{color:#ccc}.day-cell.today{font-weight:600;color:var(--tng-primary, #6200ee);border:1px solid var(--tng-primary, #6200ee)}.day-cell.selected,.day-cell.range-start,.day-cell.range-end{background-color:var(--tng-primary, #6200ee);color:var(--tng-primary-contrast, #fff)}.day-cell.selected.today,.day-cell.range-start.today,.day-cell.range-end.today{border-color:transparent}.day-cell.in-range{background-color:color-mix(in srgb,var(--tng-primary, #6200ee),white 80%);border-radius:0;color:var(--tng-primary, #6200ee)}.day-cell.in-range.range-start{border-top-right-radius:0;border-bottom-right-radius:0}.day-cell.in-range.range-end{border-top-left-radius:0;border-bottom-left-radius:0}.day-cell.range-start{border-radius:50% 0 0 50%;position:relative}.day-cell.range-start:after{content:\"\";position:absolute;inset:0 0 0 50%;background-color:color-mix(in srgb,var(--tng-primary, #6200ee),white 80%);z-index:-1}.day-cell.range-end{border-radius:0 50% 50% 0;position:relative}.day-cell.range-end:after{content:\"\";position:absolute;inset:0 50% 0 0;background-color:color-mix(in srgb,var(--tng-primary, #6200ee),white 80%);z-index:-1}.day-cell.selected{border-radius:50%}.day-cell.disabled{opacity:.3;pointer-events:none;cursor:not-allowed}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }] });
436
+ ], ngImport: i0, template: "<div class=\"tng-datepicker-container\" [class.focused]=\"isOpen()\" [class.has-value]=\"formattedValue\" [class.disabled]=\"disabled()\">\n <!-- Trigger Field (Reusing Input Style) -->\n <div class=\"tng-input-trigger\" (click)=\"toggleCalendar()\">\n <fieldset class=\"tng-fieldset\" aria-hidden=\"true\">\n <legend class=\"tng-legend\"><span>{{ label() }}</span></legend>\n </fieldset>\n <label class=\"tng-label\">{{ label() }}</label>\n <div class=\"tng-input-display\">\n {{ formattedValue || (isOpen() ? placeholder() : '') }}\n </div>\n <span class=\"material-icons tng-icon\">calendar_today</span>\n </div>\n\n <!-- Calendar Popup -->\n @if (isOpen()) {\n <div class=\"tng-calendar-popup\">\n <div class=\"tng-calendar-header\">\n <button type=\"button\" class=\"nav-btn\" (click)=\"prevMonth($event)\">\n <span class=\"material-icons\">chevron_left</span>\n </button>\n <span class=\"current-month\">{{ currentMonthYear }}</span>\n <button type=\"button\" class=\"nav-btn\" (click)=\"nextMonth($event)\">\n <span class=\"material-icons\">chevron_right</span>\n </button>\n </div>\n\n <div class=\"tng-calendar-grid\">\n @for (day of daysOfWeek; track day) {\n <div class=\"day-name\">{{ day }}</div>\n }\n @for (date of calendarDays(); track date.getTime()) {\n <div\n class=\"day-cell\"\n [class.not-current-month]=\"!isCurrentMonth(date)\"\n [class.today]=\"isToday(date)\"\n [class.selected]=\"isSelected(date)\"\n [class.in-range]=\"isInRange(date)\"\n [class.range-start]=\"mode() === 'range' && isSameDay(date, rangeValue.start)\"\n [class.range-end]=\"mode() === 'range' && isSameDay(date, rangeValue.end)\"\n [class.disabled]=\"isDisabled(date)\"\n (click)=\"selectDate(date)\"\n >\n {{ date.getDate() }}\n </div>\n }\n </div>\n </div>\n }\n</div>\n", styles: [":host{display:block;margin-bottom:1.5rem;font-family:var(--tng-font-family, \"Inter\", sans-serif);position:relative}.tng-datepicker-container{position:relative}.tng-datepicker-container.disabled{opacity:.6;pointer-events:none}.tng-datepicker-container.disabled .tng-fieldset{border-color:var(--tng-border, #ccc);background-color:var(--tng-background, #f9f9f9)}.tng-input-trigger{position:relative;border-radius:var(--tng-border-radius, 4px);padding:0 16px;height:48px;display:flex;align-items:center;cursor:pointer}.tng-input-trigger:hover .tng-fieldset{border-color:color-mix(in srgb,var(--tng-border, #999),black 20%)}.tng-fieldset{position:absolute;inset:0 0 5px;margin:0;padding:0 12px;border:1px solid var(--tng-border, #999);border-radius:var(--tng-border-radius, 4px);background-color:var(--tng-surface);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);pointer-events:none;transition:border-color .2s ease}.tng-legend{width:auto;max-width:0;height:11px;font-size:.75em;visibility:hidden;white-space:nowrap;padding-inline:0px}.tng-legend span{padding:0 2px;visibility:visible;opacity:0}.tng-label{position:absolute;top:50%;left:16px;transform:translateY(-50%);color:var(--tng-text-secondary, #666);font-size:16px;font-weight:400;pointer-events:none;transform-origin:left top;transition:transform .2s cubic-bezier(.4,0,.2,1),color .2s ease}.tng-input-display{flex:1;font-size:16px;color:var(--tng-text, #333);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center}.tng-icon{color:var(--tng-text-secondary, #666);font-size:20px;margin-left:8px}.tng-datepicker-container.focused .tng-fieldset,.tng-datepicker-container.has-value .tng-fieldset{border-color:var(--tng-primary, #6200ee);border-width:2px}.tng-datepicker-container.focused .tng-label,.tng-datepicker-container.has-value .tng-label{color:var(--tng-primary, #6200ee);transform:translateY(-24px) scale(.75)}.tng-datepicker-container.focused .tng-legend,.tng-datepicker-container.has-value .tng-legend{max-width:100%}.tng-datepicker-container.focused .tng-label{color:var(--tng-primary, #6200ee)}.tng-calendar-popup{position:absolute;top:100%;left:0;z-index:1000;margin-top:4px;background:var(--tng-surface, #fff);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-radius:8px;box-shadow:var(--tng-shadow-md, 0 4px 20px rgba(0, 0, 0, .15));padding:16px;width:300px;animation:fadeIn .2s ease;border:1px solid var(--tng-border, #eee)}@keyframes fadeIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.tng-calendar-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:16px}.tng-calendar-header .current-month{font-weight:600;font-size:16px;color:var(--tng-text, #333)}.tng-calendar-header .nav-btn{background:none;border:none;cursor:pointer;padding:4px;border-radius:50%;display:flex;align-items:center;justify-content:center;color:var(--tng-text-secondary, #666)}.tng-calendar-header .nav-btn:hover{background-color:var(--tng-background, #f5f5f5)}.tng-calendar-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;text-align:center}.day-name{font-size:12px;color:var(--tng-text-secondary, #666);font-weight:500;margin-bottom:8px}.day-cell{height:36px;display:flex;align-items:center;justify-content:center;font-size:14px;cursor:pointer;border-radius:50%;transition:all .2s ease;position:relative;color:var(--tng-text, #333)}.day-cell:hover:not(.disabled):not(.selected):not(.range-start):not(.range-end){background-color:var(--tng-background, #f5f5f5)}.day-cell.not-current-month{color:#ccc}.day-cell.today{font-weight:600;color:var(--tng-primary, #6200ee);border:1px solid var(--tng-primary, #6200ee)}.day-cell.selected,.day-cell.range-start,.day-cell.range-end{background-color:var(--tng-primary, #6200ee);color:var(--tng-primary-contrast, #fff)}.day-cell.selected.today,.day-cell.range-start.today,.day-cell.range-end.today{border-color:transparent}.day-cell.in-range{background-color:color-mix(in srgb,var(--tng-primary, #6200ee),white 80%);border-radius:0;color:var(--tng-primary, #6200ee)}.day-cell.in-range.range-start{border-top-right-radius:0;border-bottom-right-radius:0}.day-cell.in-range.range-end{border-top-left-radius:0;border-bottom-left-radius:0}.day-cell.range-start{border-radius:50% 0 0 50%;position:relative}.day-cell.range-start:after{content:\"\";position:absolute;inset:0 0 0 50%;background-color:color-mix(in srgb,var(--tng-primary, #6200ee),white 80%);z-index:-1}.day-cell.range-end{border-radius:0 50% 50% 0;position:relative}.day-cell.range-end:after{content:\"\";position:absolute;inset:0 50% 0 0;background-color:color-mix(in srgb,var(--tng-primary, #6200ee),white 80%);z-index:-1}.day-cell.selected{border-radius:50%}.day-cell.disabled{opacity:.3;pointer-events:none;cursor:not-allowed}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }] });
324
437
  }
325
438
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TecnualDatepickerComponent, decorators: [{
326
439
  type: Component,
@@ -330,7 +443,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
330
443
  useExisting: forwardRef(() => TecnualDatepickerComponent),
331
444
  multi: true
332
445
  }
333
- ], template: "<div class=\"tng-datepicker-container\" [class.focused]=\"isOpen()\" [class.has-value]=\"formattedValue\" [class.disabled]=\"disabled()\">\n <!-- Trigger Field (Reusing Input Style) -->\n <div class=\"tng-input-trigger\" (click)=\"toggleCalendar()\">\n <fieldset class=\"tng-fieldset\" aria-hidden=\"true\">\n <legend class=\"tng-legend\"><span>{{ label() }}</span></legend>\n </fieldset>\n <label class=\"tng-label\">{{ label() }}</label>\n <div class=\"tng-input-display\">\n {{ formattedValue || (isOpen() ? placeholder() : '') }}\n </div>\n <span class=\"material-icons tng-icon\">calendar_today</span>\n </div>\n\n <!-- Calendar Popup -->\n @if (isOpen()) {\n <div class=\"tng-calendar-popup\">\n <div class=\"tng-calendar-header\">\n <button type=\"button\" class=\"nav-btn\" (click)=\"prevMonth($event)\">\n <span class=\"material-icons\">chevron_left</span>\n </button>\n <span class=\"current-month\">{{ currentMonthYear }}</span>\n <button type=\"button\" class=\"nav-btn\" (click)=\"nextMonth($event)\">\n <span class=\"material-icons\">chevron_right</span>\n </button>\n </div>\n\n <div class=\"tng-calendar-grid\">\n @for (day of daysOfWeek; track day) {\n <div class=\"day-name\">{{ day }}</div>\n }\n @for (date of calendarDays(); track date.getTime()) {\n <div\n class=\"day-cell\"\n [class.not-current-month]=\"!isCurrentMonth(date)\"\n [class.today]=\"isToday(date)\"\n [class.selected]=\"isSelected(date)\"\n [class.in-range]=\"isInRange(date)\"\n [class.range-start]=\"mode() === 'range' && isSameDay(date, rangeValue.start)\"\n [class.range-end]=\"mode() === 'range' && isSameDay(date, rangeValue.end)\"\n [class.disabled]=\"isDisabled(date)\"\n (click)=\"selectDate(date)\"\n >\n {{ date.getDate() }}\n </div>\n }\n </div>\n </div>\n }\n</div>\n", styles: [":host{display:block;margin-bottom:1.5rem;font-family:var(--tng-font-family, \"Inter\", sans-serif);position:relative}.tng-datepicker-container{position:relative}.tng-datepicker-container.disabled{opacity:.6;pointer-events:none}.tng-datepicker-container.disabled .tng-fieldset{border-color:var(--tng-border, #ccc);background-color:var(--tng-background, #f9f9f9)}.tng-input-trigger{position:relative;border-radius:var(--tng-border-radius, 4px);padding:0 16px;height:48px;display:flex;align-items:center;cursor:pointer}.tng-input-trigger:hover .tng-fieldset{border-color:color-mix(in srgb,var(--tng-border, #999),black 20%)}.tng-fieldset{position:absolute;inset:0 0 5px;margin:0;padding:0 12px;border:1px solid var(--tng-border, #999);border-radius:var(--tng-border-radius, 4px);pointer-events:none;transition:border-color .2s ease}.tng-legend{width:auto;max-width:0;height:11px;font-size:.75em;visibility:hidden;white-space:nowrap;padding-inline:0px}.tng-legend span{padding:0 2px;visibility:visible;opacity:0}.tng-label{position:absolute;top:50%;left:16px;transform:translateY(-50%);color:var(--tng-text-secondary, #666);font-size:16px;font-weight:400;pointer-events:none;transform-origin:left top;transition:transform .2s cubic-bezier(.4,0,.2,1),color .2s ease}.tng-input-display{flex:1;font-size:16px;color:var(--tng-text, #333);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center}.tng-icon{color:var(--tng-text-secondary, #666);font-size:20px;margin-left:8px}.tng-datepicker-container.focused .tng-fieldset,.tng-datepicker-container.has-value .tng-fieldset{border-color:var(--tng-primary, #6200ee);border-width:2px}.tng-datepicker-container.focused .tng-label,.tng-datepicker-container.has-value .tng-label{color:var(--tng-primary, #6200ee);transform:translateY(-24px) scale(.75)}.tng-datepicker-container.focused .tng-legend,.tng-datepicker-container.has-value .tng-legend{max-width:100%}.tng-datepicker-container.focused .tng-label{color:var(--tng-primary, #6200ee)}.tng-calendar-popup{position:absolute;top:100%;left:0;z-index:1000;margin-top:4px;background:var(--tng-surface, #fff);border-radius:8px;box-shadow:var(--tng-shadow-md, 0 4px 20px rgba(0, 0, 0, .15));padding:16px;width:300px;animation:fadeIn .2s ease;border:1px solid var(--tng-border, #eee)}@keyframes fadeIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.tng-calendar-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:16px}.tng-calendar-header .current-month{font-weight:600;font-size:16px;color:var(--tng-text, #333)}.tng-calendar-header .nav-btn{background:none;border:none;cursor:pointer;padding:4px;border-radius:50%;display:flex;align-items:center;justify-content:center;color:var(--tng-text-secondary, #666)}.tng-calendar-header .nav-btn:hover{background-color:var(--tng-background, #f5f5f5)}.tng-calendar-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;text-align:center}.day-name{font-size:12px;color:var(--tng-text-secondary, #666);font-weight:500;margin-bottom:8px}.day-cell{height:36px;display:flex;align-items:center;justify-content:center;font-size:14px;cursor:pointer;border-radius:50%;transition:all .2s ease;position:relative;color:var(--tng-text, #333)}.day-cell:hover:not(.disabled):not(.selected):not(.range-start):not(.range-end){background-color:var(--tng-background, #f5f5f5)}.day-cell.not-current-month{color:#ccc}.day-cell.today{font-weight:600;color:var(--tng-primary, #6200ee);border:1px solid var(--tng-primary, #6200ee)}.day-cell.selected,.day-cell.range-start,.day-cell.range-end{background-color:var(--tng-primary, #6200ee);color:var(--tng-primary-contrast, #fff)}.day-cell.selected.today,.day-cell.range-start.today,.day-cell.range-end.today{border-color:transparent}.day-cell.in-range{background-color:color-mix(in srgb,var(--tng-primary, #6200ee),white 80%);border-radius:0;color:var(--tng-primary, #6200ee)}.day-cell.in-range.range-start{border-top-right-radius:0;border-bottom-right-radius:0}.day-cell.in-range.range-end{border-top-left-radius:0;border-bottom-left-radius:0}.day-cell.range-start{border-radius:50% 0 0 50%;position:relative}.day-cell.range-start:after{content:\"\";position:absolute;inset:0 0 0 50%;background-color:color-mix(in srgb,var(--tng-primary, #6200ee),white 80%);z-index:-1}.day-cell.range-end{border-radius:0 50% 50% 0;position:relative}.day-cell.range-end:after{content:\"\";position:absolute;inset:0 50% 0 0;background-color:color-mix(in srgb,var(--tng-primary, #6200ee),white 80%);z-index:-1}.day-cell.selected{border-radius:50%}.day-cell.disabled{opacity:.3;pointer-events:none;cursor:not-allowed}\n"] }]
446
+ ], template: "<div class=\"tng-datepicker-container\" [class.focused]=\"isOpen()\" [class.has-value]=\"formattedValue\" [class.disabled]=\"disabled()\">\n <!-- Trigger Field (Reusing Input Style) -->\n <div class=\"tng-input-trigger\" (click)=\"toggleCalendar()\">\n <fieldset class=\"tng-fieldset\" aria-hidden=\"true\">\n <legend class=\"tng-legend\"><span>{{ label() }}</span></legend>\n </fieldset>\n <label class=\"tng-label\">{{ label() }}</label>\n <div class=\"tng-input-display\">\n {{ formattedValue || (isOpen() ? placeholder() : '') }}\n </div>\n <span class=\"material-icons tng-icon\">calendar_today</span>\n </div>\n\n <!-- Calendar Popup -->\n @if (isOpen()) {\n <div class=\"tng-calendar-popup\">\n <div class=\"tng-calendar-header\">\n <button type=\"button\" class=\"nav-btn\" (click)=\"prevMonth($event)\">\n <span class=\"material-icons\">chevron_left</span>\n </button>\n <span class=\"current-month\">{{ currentMonthYear }}</span>\n <button type=\"button\" class=\"nav-btn\" (click)=\"nextMonth($event)\">\n <span class=\"material-icons\">chevron_right</span>\n </button>\n </div>\n\n <div class=\"tng-calendar-grid\">\n @for (day of daysOfWeek; track day) {\n <div class=\"day-name\">{{ day }}</div>\n }\n @for (date of calendarDays(); track date.getTime()) {\n <div\n class=\"day-cell\"\n [class.not-current-month]=\"!isCurrentMonth(date)\"\n [class.today]=\"isToday(date)\"\n [class.selected]=\"isSelected(date)\"\n [class.in-range]=\"isInRange(date)\"\n [class.range-start]=\"mode() === 'range' && isSameDay(date, rangeValue.start)\"\n [class.range-end]=\"mode() === 'range' && isSameDay(date, rangeValue.end)\"\n [class.disabled]=\"isDisabled(date)\"\n (click)=\"selectDate(date)\"\n >\n {{ date.getDate() }}\n </div>\n }\n </div>\n </div>\n }\n</div>\n", styles: [":host{display:block;margin-bottom:1.5rem;font-family:var(--tng-font-family, \"Inter\", sans-serif);position:relative}.tng-datepicker-container{position:relative}.tng-datepicker-container.disabled{opacity:.6;pointer-events:none}.tng-datepicker-container.disabled .tng-fieldset{border-color:var(--tng-border, #ccc);background-color:var(--tng-background, #f9f9f9)}.tng-input-trigger{position:relative;border-radius:var(--tng-border-radius, 4px);padding:0 16px;height:48px;display:flex;align-items:center;cursor:pointer}.tng-input-trigger:hover .tng-fieldset{border-color:color-mix(in srgb,var(--tng-border, #999),black 20%)}.tng-fieldset{position:absolute;inset:0 0 5px;margin:0;padding:0 12px;border:1px solid var(--tng-border, #999);border-radius:var(--tng-border-radius, 4px);background-color:var(--tng-surface);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);pointer-events:none;transition:border-color .2s ease}.tng-legend{width:auto;max-width:0;height:11px;font-size:.75em;visibility:hidden;white-space:nowrap;padding-inline:0px}.tng-legend span{padding:0 2px;visibility:visible;opacity:0}.tng-label{position:absolute;top:50%;left:16px;transform:translateY(-50%);color:var(--tng-text-secondary, #666);font-size:16px;font-weight:400;pointer-events:none;transform-origin:left top;transition:transform .2s cubic-bezier(.4,0,.2,1),color .2s ease}.tng-input-display{flex:1;font-size:16px;color:var(--tng-text, #333);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;display:flex;align-items:center}.tng-icon{color:var(--tng-text-secondary, #666);font-size:20px;margin-left:8px}.tng-datepicker-container.focused .tng-fieldset,.tng-datepicker-container.has-value .tng-fieldset{border-color:var(--tng-primary, #6200ee);border-width:2px}.tng-datepicker-container.focused .tng-label,.tng-datepicker-container.has-value .tng-label{color:var(--tng-primary, #6200ee);transform:translateY(-24px) scale(.75)}.tng-datepicker-container.focused .tng-legend,.tng-datepicker-container.has-value .tng-legend{max-width:100%}.tng-datepicker-container.focused .tng-label{color:var(--tng-primary, #6200ee)}.tng-calendar-popup{position:absolute;top:100%;left:0;z-index:1000;margin-top:4px;background:var(--tng-surface, #fff);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-radius:8px;box-shadow:var(--tng-shadow-md, 0 4px 20px rgba(0, 0, 0, .15));padding:16px;width:300px;animation:fadeIn .2s ease;border:1px solid var(--tng-border, #eee)}@keyframes fadeIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.tng-calendar-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:16px}.tng-calendar-header .current-month{font-weight:600;font-size:16px;color:var(--tng-text, #333)}.tng-calendar-header .nav-btn{background:none;border:none;cursor:pointer;padding:4px;border-radius:50%;display:flex;align-items:center;justify-content:center;color:var(--tng-text-secondary, #666)}.tng-calendar-header .nav-btn:hover{background-color:var(--tng-background, #f5f5f5)}.tng-calendar-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;text-align:center}.day-name{font-size:12px;color:var(--tng-text-secondary, #666);font-weight:500;margin-bottom:8px}.day-cell{height:36px;display:flex;align-items:center;justify-content:center;font-size:14px;cursor:pointer;border-radius:50%;transition:all .2s ease;position:relative;color:var(--tng-text, #333)}.day-cell:hover:not(.disabled):not(.selected):not(.range-start):not(.range-end){background-color:var(--tng-background, #f5f5f5)}.day-cell.not-current-month{color:#ccc}.day-cell.today{font-weight:600;color:var(--tng-primary, #6200ee);border:1px solid var(--tng-primary, #6200ee)}.day-cell.selected,.day-cell.range-start,.day-cell.range-end{background-color:var(--tng-primary, #6200ee);color:var(--tng-primary-contrast, #fff)}.day-cell.selected.today,.day-cell.range-start.today,.day-cell.range-end.today{border-color:transparent}.day-cell.in-range{background-color:color-mix(in srgb,var(--tng-primary, #6200ee),white 80%);border-radius:0;color:var(--tng-primary, #6200ee)}.day-cell.in-range.range-start{border-top-right-radius:0;border-bottom-right-radius:0}.day-cell.in-range.range-end{border-top-left-radius:0;border-bottom-left-radius:0}.day-cell.range-start{border-radius:50% 0 0 50%;position:relative}.day-cell.range-start:after{content:\"\";position:absolute;inset:0 0 0 50%;background-color:color-mix(in srgb,var(--tng-primary, #6200ee),white 80%);z-index:-1}.day-cell.range-end{border-radius:0 50% 50% 0;position:relative}.day-cell.range-end:after{content:\"\";position:absolute;inset:0 50% 0 0;background-color:color-mix(in srgb,var(--tng-primary, #6200ee),white 80%);z-index:-1}.day-cell.selected{border-radius:50%}.day-cell.disabled{opacity:.3;pointer-events:none;cursor:not-allowed}\n"] }]
334
447
  }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], minDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDate", required: false }] }], maxDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDate", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }, { type: i0.Output, args: ["disabledChange"] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], onClickOutside: [{
335
448
  type: HostListener,
336
449
  args: ['document:click', ['$event']]
@@ -410,11 +523,11 @@ class TecnualTableComponent {
410
523
  this.onSearch(input.value);
411
524
  }
412
525
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TecnualTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
413
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.0", type: TecnualTableComponent, isStandalone: true, selector: "tng-table", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, filterable: { classPropertyName: "filterable", publicName: "filterable", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"tng-table-container\">\n <!-- Toolbar -->\n @if (filterable()) {\n <div class=\"tng-table-toolbar\">\n <div class=\"tng-table-search\">\n <tng-input\n [placeholder]=\"'Search...'\"\n (input)=\"onSearchInput($event)\"\n ></tng-input>\n </div>\n </div>\n }\n\n <!-- Table -->\n <div class=\"tng-table-wrapper\">\n <table class=\"tng-table\">\n <thead>\n <tr>\n @for (col of columns(); track col.key) {\n <th \n [style.width]=\"col.width\"\n [class.sortable]=\"col.sortable\"\n (click)=\"onSort(col)\"\n >\n <div class=\"th-content\">\n {{ col.label }}\n @if (sortColumn() === col.key) {\n <span class=\"sort-indicator\">\n {{ sortDirection() === 'asc' ? '\u2191' : '\u2193' }}\n </span>\n }\n </div>\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of paginatedData(); track row) {\n <tr>\n @for (col of columns(); track col.key) {\n <td>\n @if (col.template) {\n <ng-container *ngTemplateOutlet=\"col.template; context: { $implicit: row[col.key], row: row }\"></ng-container>\n } @else {\n {{ row[col.key] }}\n }\n </td>\n }\n </tr>\n }\n @if (paginatedData().length === 0) {\n <tr class=\"no-data-row\">\n <td [attr.colspan]=\"columns().length\">\n No data found\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n\n <!-- Pagination -->\n @if (totalPages() > 1) {\n <div class=\"tng-table-pagination\">\n <div class=\"pagination-info\">\n Page {{ currentPage() }} of {{ totalPages() }}\n </div>\n <div class=\"pagination-controls\">\n <button \n class=\"tng-btn-icon\" \n [disabled]=\"currentPage() === 1\"\n (click)=\"setPage(currentPage() - 1)\"\n >\n \u2039\n </button>\n \n @for (page of [].constructor(totalPages()); track $index; let i = $index) {\n @if (i + 1 === currentPage() || i + 1 === 1 || i + 1 === totalPages() || (i + 1 >= currentPage() - 1 && i + 1 <= currentPage() + 1)) {\n <button \n class=\"tng-btn-page\"\n [class.active]=\"currentPage() === i + 1\"\n (click)=\"setPage(i + 1)\"\n >\n {{ i + 1 }}\n </button>\n }\n @if ((i + 1 === 2 && currentPage() > 4) || (i + 1 === totalPages() - 1 && currentPage() < totalPages() - 3)) {\n <span class=\"pagination-dots\">...</span>\n }\n }\n\n <button \n class=\"tng-btn-icon\" \n [disabled]=\"currentPage() === totalPages()\"\n (click)=\"setPage(currentPage() + 1)\"\n >\n \u203A\n </button>\n </div>\n </div>\n }\n</div>\n", styles: [".tng-table-container{display:flex;flex-direction:column;gap:var(--tng-spacing-unit, 16px);width:100%;background:var(--tng-surface, #fff);border-radius:var(--tng-border-radius, 8px);box-shadow:var(--tng-shadow-sm, 0 1px 3px rgba(0, 0, 0, .1));padding:var(--tng-spacing-unit, 16px);box-sizing:border-box}.tng-table-toolbar{display:flex;justify-content:flex-end;margin-bottom:var(--tng-spacing-unit, 8px)}.tng-table-search{width:100%;max-width:300px}.tng-table-wrapper{overflow-x:auto;width:100%;border:1px solid var(--tng-border, #e0e0e0);border-radius:var(--tng-border-radius, 4px)}.tng-table{width:100%;border-collapse:collapse;font-family:var(--tng-font-family, sans-serif);font-size:var(--tng-font-size-base, 14px)}.tng-table th,.tng-table td{padding:12px 16px;text-align:left;border-bottom:1px solid var(--tng-border, #e0e0e0)}.tng-table th{background-color:var(--tng-background, #fafafa);font-weight:var(--tng-font-weight-medium, 500);color:var(--tng-text-secondary, #666);white-space:nowrap;-webkit-user-select:none;user-select:none}.tng-table th.sortable{cursor:pointer;transition:background-color .2s}.tng-table th.sortable:hover{background-color:#ededed}.tng-table tr:last-child td{border-bottom:none}.tng-table tr:hover td{background-color:#00000005}.th-content{display:flex;align-items:center;gap:4px}.sort-indicator{font-size:12px}.no-data-row{text-align:center;color:var(--tng-text-secondary, #666);padding:24px}.tng-table-pagination{display:flex;justify-content:space-between;align-items:center;padding-top:var(--tng-spacing-unit, 8px);flex-wrap:wrap;gap:16px}.pagination-info{color:var(--tng-text-secondary, #666);font-size:.9em}.pagination-controls{display:flex;gap:4px;align-items:center}.tng-btn-icon,.tng-btn-page{display:inline-flex;align-items:center;justify-content:center;min-width:32px;height:32px;padding:0 6px;border:1px solid var(--tng-border, #e0e0e0);background:var(--tng-surface, #fff);border-radius:var(--tng-border-radius, 4px);cursor:pointer;color:var(--tng-text, #333);transition:all .2s}.tng-btn-icon:hover:not(:disabled),.tng-btn-page:hover:not(:disabled){background-color:var(--tng-background, #f5f5f5);border-color:var(--tng-primary, #3f51b5);color:var(--tng-primary, #3f51b5)}.tng-btn-icon:disabled,.tng-btn-page:disabled{opacity:.5;cursor:not-allowed}.tng-btn-icon.active,.tng-btn-page.active{background-color:var(--tng-primary, #3f51b5);color:var(--tng-primary-contrast, #fff);border-color:var(--tng-primary, #3f51b5)}.pagination-dots{display:inline-flex;align-items:center;justify-content:center;width:32px;color:var(--tng-text-secondary, #666)}@media(max-width:600px){.tng-table-pagination{justify-content:center;flex-direction:column}.tng-table-toolbar{justify-content:stretch}.tng-table-search{max-width:none}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: TecnualInputComponent, selector: "tng-input", inputs: ["label", "type", "placeholder", "required", "disabled", "id"], outputs: ["disabledChange"] }] });
526
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.0", type: TecnualTableComponent, isStandalone: true, selector: "tng-table", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, filterable: { classPropertyName: "filterable", publicName: "filterable", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"tng-table-container\">\n <!-- Toolbar -->\n @if (filterable()) {\n <div class=\"tng-table-toolbar\">\n <div class=\"tng-table-search\">\n <tng-input\n [placeholder]=\"'Search...'\"\n (input)=\"onSearchInput($event)\"\n ></tng-input>\n </div>\n </div>\n }\n\n <!-- Table -->\n <div class=\"tng-table-wrapper\">\n <table class=\"tng-table\">\n <thead>\n <tr>\n @for (col of columns(); track col.key) {\n <th \n [style.width]=\"col.width\"\n [class.sortable]=\"col.sortable\"\n (click)=\"onSort(col)\"\n >\n <div class=\"th-content\">\n {{ col.label }}\n @if (sortColumn() === col.key) {\n <span class=\"sort-indicator\">\n {{ sortDirection() === 'asc' ? '\u2191' : '\u2193' }}\n </span>\n }\n </div>\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of paginatedData(); track row) {\n <tr>\n @for (col of columns(); track col.key) {\n <td>\n @if (col.template) {\n <ng-container *ngTemplateOutlet=\"col.template; context: { $implicit: row[col.key], row: row }\"></ng-container>\n } @else {\n {{ row[col.key] }}\n }\n </td>\n }\n </tr>\n }\n @if (paginatedData().length === 0) {\n <tr class=\"no-data-row\">\n <td [attr.colspan]=\"columns().length\">\n No data found\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n\n <!-- Pagination -->\n @if (totalPages() > 1) {\n <div class=\"tng-table-pagination\">\n <div class=\"pagination-info\">\n Page {{ currentPage() }} of {{ totalPages() }}\n </div>\n <div class=\"pagination-controls\">\n <button \n class=\"tng-btn-icon\" \n [disabled]=\"currentPage() === 1\"\n (click)=\"setPage(currentPage() - 1)\"\n >\n \u2039\n </button>\n \n @for (page of [].constructor(totalPages()); track $index; let i = $index) {\n @if (i + 1 === currentPage() || i + 1 === 1 || i + 1 === totalPages() || (i + 1 >= currentPage() - 1 && i + 1 <= currentPage() + 1)) {\n <button \n class=\"tng-btn-page\"\n [class.active]=\"currentPage() === i + 1\"\n (click)=\"setPage(i + 1)\"\n >\n {{ i + 1 }}\n </button>\n }\n @if ((i + 1 === 2 && currentPage() > 4) || (i + 1 === totalPages() - 1 && currentPage() < totalPages() - 3)) {\n <span class=\"pagination-dots\">...</span>\n }\n }\n\n <button \n class=\"tng-btn-icon\" \n [disabled]=\"currentPage() === totalPages()\"\n (click)=\"setPage(currentPage() + 1)\"\n >\n \u203A\n </button>\n </div>\n </div>\n }\n</div>\n", styles: [".tng-table-container{display:flex;flex-direction:column;gap:var(--tng-spacing-unit, 16px);width:100%;background:var(--tng-surface, #fff);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid var(--tng-border);border-radius:var(--tng-border-radius, 8px);box-shadow:var(--tng-shadow-sm, 0 1px 3px rgba(0, 0, 0, .1));padding:var(--tng-spacing-unit, 16px);box-sizing:border-box}.tng-table-toolbar{display:flex;justify-content:flex-end;margin-bottom:var(--tng-spacing-unit, 8px)}.tng-table-search{width:100%;max-width:300px}.tng-table-wrapper{overflow-x:auto;width:100%;border:1px solid var(--tng-border, #e0e0e0);border-radius:var(--tng-border-radius, 4px)}.tng-table{width:100%;border-collapse:collapse;font-family:var(--tng-font-family, sans-serif);font-size:var(--tng-font-size-base, 14px)}.tng-table th,.tng-table td{padding:12px 16px;text-align:left;border-bottom:1px solid var(--tng-border, #e0e0e0)}.tng-table th{background-color:var(--tng-background, #fafafa);font-weight:var(--tng-font-weight-medium, 500);color:var(--tng-text-secondary, #666);white-space:nowrap;-webkit-user-select:none;user-select:none}.tng-table th.sortable{cursor:pointer;transition:background-color .2s}.tng-table th.sortable:hover{background-color:#ededed}.tng-table tr:last-child td{border-bottom:none}.tng-table tr:hover td{background-color:#00000005}.th-content{display:flex;align-items:center;gap:4px}.sort-indicator{font-size:12px}.no-data-row{text-align:center;color:var(--tng-text-secondary, #666);padding:24px}.tng-table-pagination{display:flex;justify-content:space-between;align-items:center;padding-top:var(--tng-spacing-unit, 8px);flex-wrap:wrap;gap:16px}.pagination-info{color:var(--tng-text-secondary, #666);font-size:.9em}.pagination-controls{display:flex;gap:4px;align-items:center}.tng-btn-icon,.tng-btn-page{display:inline-flex;align-items:center;justify-content:center;min-width:32px;height:32px;padding:0 6px;border:1px solid var(--tng-border, #e0e0e0);background:var(--tng-surface, #fff);border-radius:var(--tng-border-radius, 4px);cursor:pointer;color:var(--tng-text, #333);transition:all .2s}.tng-btn-icon:hover:not(:disabled),.tng-btn-page:hover:not(:disabled){background-color:var(--tng-background, #f5f5f5);border-color:var(--tng-primary, #3f51b5);color:var(--tng-primary, #3f51b5)}.tng-btn-icon:disabled,.tng-btn-page:disabled{opacity:.5;cursor:not-allowed}.tng-btn-icon.active,.tng-btn-page.active{background-color:var(--tng-primary, #3f51b5);color:var(--tng-primary-contrast, #fff);border-color:var(--tng-primary, #3f51b5)}.pagination-dots{display:inline-flex;align-items:center;justify-content:center;width:32px;color:var(--tng-text-secondary, #666)}@media(max-width:600px){.tng-table-pagination{justify-content:center;flex-direction:column}.tng-table-toolbar{justify-content:stretch}.tng-table-search{max-width:none}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: TecnualInputComponent, selector: "tng-input", inputs: ["label", "type", "placeholder", "required", "disabled", "id"], outputs: ["disabledChange"] }] });
414
527
  }
415
528
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TecnualTableComponent, decorators: [{
416
529
  type: Component,
417
- args: [{ selector: 'tng-table', standalone: true, imports: [CommonModule, FormsModule, TecnualInputComponent], template: "<div class=\"tng-table-container\">\n <!-- Toolbar -->\n @if (filterable()) {\n <div class=\"tng-table-toolbar\">\n <div class=\"tng-table-search\">\n <tng-input\n [placeholder]=\"'Search...'\"\n (input)=\"onSearchInput($event)\"\n ></tng-input>\n </div>\n </div>\n }\n\n <!-- Table -->\n <div class=\"tng-table-wrapper\">\n <table class=\"tng-table\">\n <thead>\n <tr>\n @for (col of columns(); track col.key) {\n <th \n [style.width]=\"col.width\"\n [class.sortable]=\"col.sortable\"\n (click)=\"onSort(col)\"\n >\n <div class=\"th-content\">\n {{ col.label }}\n @if (sortColumn() === col.key) {\n <span class=\"sort-indicator\">\n {{ sortDirection() === 'asc' ? '\u2191' : '\u2193' }}\n </span>\n }\n </div>\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of paginatedData(); track row) {\n <tr>\n @for (col of columns(); track col.key) {\n <td>\n @if (col.template) {\n <ng-container *ngTemplateOutlet=\"col.template; context: { $implicit: row[col.key], row: row }\"></ng-container>\n } @else {\n {{ row[col.key] }}\n }\n </td>\n }\n </tr>\n }\n @if (paginatedData().length === 0) {\n <tr class=\"no-data-row\">\n <td [attr.colspan]=\"columns().length\">\n No data found\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n\n <!-- Pagination -->\n @if (totalPages() > 1) {\n <div class=\"tng-table-pagination\">\n <div class=\"pagination-info\">\n Page {{ currentPage() }} of {{ totalPages() }}\n </div>\n <div class=\"pagination-controls\">\n <button \n class=\"tng-btn-icon\" \n [disabled]=\"currentPage() === 1\"\n (click)=\"setPage(currentPage() - 1)\"\n >\n \u2039\n </button>\n \n @for (page of [].constructor(totalPages()); track $index; let i = $index) {\n @if (i + 1 === currentPage() || i + 1 === 1 || i + 1 === totalPages() || (i + 1 >= currentPage() - 1 && i + 1 <= currentPage() + 1)) {\n <button \n class=\"tng-btn-page\"\n [class.active]=\"currentPage() === i + 1\"\n (click)=\"setPage(i + 1)\"\n >\n {{ i + 1 }}\n </button>\n }\n @if ((i + 1 === 2 && currentPage() > 4) || (i + 1 === totalPages() - 1 && currentPage() < totalPages() - 3)) {\n <span class=\"pagination-dots\">...</span>\n }\n }\n\n <button \n class=\"tng-btn-icon\" \n [disabled]=\"currentPage() === totalPages()\"\n (click)=\"setPage(currentPage() + 1)\"\n >\n \u203A\n </button>\n </div>\n </div>\n }\n</div>\n", styles: [".tng-table-container{display:flex;flex-direction:column;gap:var(--tng-spacing-unit, 16px);width:100%;background:var(--tng-surface, #fff);border-radius:var(--tng-border-radius, 8px);box-shadow:var(--tng-shadow-sm, 0 1px 3px rgba(0, 0, 0, .1));padding:var(--tng-spacing-unit, 16px);box-sizing:border-box}.tng-table-toolbar{display:flex;justify-content:flex-end;margin-bottom:var(--tng-spacing-unit, 8px)}.tng-table-search{width:100%;max-width:300px}.tng-table-wrapper{overflow-x:auto;width:100%;border:1px solid var(--tng-border, #e0e0e0);border-radius:var(--tng-border-radius, 4px)}.tng-table{width:100%;border-collapse:collapse;font-family:var(--tng-font-family, sans-serif);font-size:var(--tng-font-size-base, 14px)}.tng-table th,.tng-table td{padding:12px 16px;text-align:left;border-bottom:1px solid var(--tng-border, #e0e0e0)}.tng-table th{background-color:var(--tng-background, #fafafa);font-weight:var(--tng-font-weight-medium, 500);color:var(--tng-text-secondary, #666);white-space:nowrap;-webkit-user-select:none;user-select:none}.tng-table th.sortable{cursor:pointer;transition:background-color .2s}.tng-table th.sortable:hover{background-color:#ededed}.tng-table tr:last-child td{border-bottom:none}.tng-table tr:hover td{background-color:#00000005}.th-content{display:flex;align-items:center;gap:4px}.sort-indicator{font-size:12px}.no-data-row{text-align:center;color:var(--tng-text-secondary, #666);padding:24px}.tng-table-pagination{display:flex;justify-content:space-between;align-items:center;padding-top:var(--tng-spacing-unit, 8px);flex-wrap:wrap;gap:16px}.pagination-info{color:var(--tng-text-secondary, #666);font-size:.9em}.pagination-controls{display:flex;gap:4px;align-items:center}.tng-btn-icon,.tng-btn-page{display:inline-flex;align-items:center;justify-content:center;min-width:32px;height:32px;padding:0 6px;border:1px solid var(--tng-border, #e0e0e0);background:var(--tng-surface, #fff);border-radius:var(--tng-border-radius, 4px);cursor:pointer;color:var(--tng-text, #333);transition:all .2s}.tng-btn-icon:hover:not(:disabled),.tng-btn-page:hover:not(:disabled){background-color:var(--tng-background, #f5f5f5);border-color:var(--tng-primary, #3f51b5);color:var(--tng-primary, #3f51b5)}.tng-btn-icon:disabled,.tng-btn-page:disabled{opacity:.5;cursor:not-allowed}.tng-btn-icon.active,.tng-btn-page.active{background-color:var(--tng-primary, #3f51b5);color:var(--tng-primary-contrast, #fff);border-color:var(--tng-primary, #3f51b5)}.pagination-dots{display:inline-flex;align-items:center;justify-content:center;width:32px;color:var(--tng-text-secondary, #666)}@media(max-width:600px){.tng-table-pagination{justify-content:center;flex-direction:column}.tng-table-toolbar{justify-content:stretch}.tng-table-search{max-width:none}}\n"] }]
530
+ args: [{ selector: 'tng-table', standalone: true, imports: [CommonModule, FormsModule, TecnualInputComponent], template: "<div class=\"tng-table-container\">\n <!-- Toolbar -->\n @if (filterable()) {\n <div class=\"tng-table-toolbar\">\n <div class=\"tng-table-search\">\n <tng-input\n [placeholder]=\"'Search...'\"\n (input)=\"onSearchInput($event)\"\n ></tng-input>\n </div>\n </div>\n }\n\n <!-- Table -->\n <div class=\"tng-table-wrapper\">\n <table class=\"tng-table\">\n <thead>\n <tr>\n @for (col of columns(); track col.key) {\n <th \n [style.width]=\"col.width\"\n [class.sortable]=\"col.sortable\"\n (click)=\"onSort(col)\"\n >\n <div class=\"th-content\">\n {{ col.label }}\n @if (sortColumn() === col.key) {\n <span class=\"sort-indicator\">\n {{ sortDirection() === 'asc' ? '\u2191' : '\u2193' }}\n </span>\n }\n </div>\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of paginatedData(); track row) {\n <tr>\n @for (col of columns(); track col.key) {\n <td>\n @if (col.template) {\n <ng-container *ngTemplateOutlet=\"col.template; context: { $implicit: row[col.key], row: row }\"></ng-container>\n } @else {\n {{ row[col.key] }}\n }\n </td>\n }\n </tr>\n }\n @if (paginatedData().length === 0) {\n <tr class=\"no-data-row\">\n <td [attr.colspan]=\"columns().length\">\n No data found\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n\n <!-- Pagination -->\n @if (totalPages() > 1) {\n <div class=\"tng-table-pagination\">\n <div class=\"pagination-info\">\n Page {{ currentPage() }} of {{ totalPages() }}\n </div>\n <div class=\"pagination-controls\">\n <button \n class=\"tng-btn-icon\" \n [disabled]=\"currentPage() === 1\"\n (click)=\"setPage(currentPage() - 1)\"\n >\n \u2039\n </button>\n \n @for (page of [].constructor(totalPages()); track $index; let i = $index) {\n @if (i + 1 === currentPage() || i + 1 === 1 || i + 1 === totalPages() || (i + 1 >= currentPage() - 1 && i + 1 <= currentPage() + 1)) {\n <button \n class=\"tng-btn-page\"\n [class.active]=\"currentPage() === i + 1\"\n (click)=\"setPage(i + 1)\"\n >\n {{ i + 1 }}\n </button>\n }\n @if ((i + 1 === 2 && currentPage() > 4) || (i + 1 === totalPages() - 1 && currentPage() < totalPages() - 3)) {\n <span class=\"pagination-dots\">...</span>\n }\n }\n\n <button \n class=\"tng-btn-icon\" \n [disabled]=\"currentPage() === totalPages()\"\n (click)=\"setPage(currentPage() + 1)\"\n >\n \u203A\n </button>\n </div>\n </div>\n }\n</div>\n", styles: [".tng-table-container{display:flex;flex-direction:column;gap:var(--tng-spacing-unit, 16px);width:100%;background:var(--tng-surface, #fff);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid var(--tng-border);border-radius:var(--tng-border-radius, 8px);box-shadow:var(--tng-shadow-sm, 0 1px 3px rgba(0, 0, 0, .1));padding:var(--tng-spacing-unit, 16px);box-sizing:border-box}.tng-table-toolbar{display:flex;justify-content:flex-end;margin-bottom:var(--tng-spacing-unit, 8px)}.tng-table-search{width:100%;max-width:300px}.tng-table-wrapper{overflow-x:auto;width:100%;border:1px solid var(--tng-border, #e0e0e0);border-radius:var(--tng-border-radius, 4px)}.tng-table{width:100%;border-collapse:collapse;font-family:var(--tng-font-family, sans-serif);font-size:var(--tng-font-size-base, 14px)}.tng-table th,.tng-table td{padding:12px 16px;text-align:left;border-bottom:1px solid var(--tng-border, #e0e0e0)}.tng-table th{background-color:var(--tng-background, #fafafa);font-weight:var(--tng-font-weight-medium, 500);color:var(--tng-text-secondary, #666);white-space:nowrap;-webkit-user-select:none;user-select:none}.tng-table th.sortable{cursor:pointer;transition:background-color .2s}.tng-table th.sortable:hover{background-color:#ededed}.tng-table tr:last-child td{border-bottom:none}.tng-table tr:hover td{background-color:#00000005}.th-content{display:flex;align-items:center;gap:4px}.sort-indicator{font-size:12px}.no-data-row{text-align:center;color:var(--tng-text-secondary, #666);padding:24px}.tng-table-pagination{display:flex;justify-content:space-between;align-items:center;padding-top:var(--tng-spacing-unit, 8px);flex-wrap:wrap;gap:16px}.pagination-info{color:var(--tng-text-secondary, #666);font-size:.9em}.pagination-controls{display:flex;gap:4px;align-items:center}.tng-btn-icon,.tng-btn-page{display:inline-flex;align-items:center;justify-content:center;min-width:32px;height:32px;padding:0 6px;border:1px solid var(--tng-border, #e0e0e0);background:var(--tng-surface, #fff);border-radius:var(--tng-border-radius, 4px);cursor:pointer;color:var(--tng-text, #333);transition:all .2s}.tng-btn-icon:hover:not(:disabled),.tng-btn-page:hover:not(:disabled){background-color:var(--tng-background, #f5f5f5);border-color:var(--tng-primary, #3f51b5);color:var(--tng-primary, #3f51b5)}.tng-btn-icon:disabled,.tng-btn-page:disabled{opacity:.5;cursor:not-allowed}.tng-btn-icon.active,.tng-btn-page.active{background-color:var(--tng-primary, #3f51b5);color:var(--tng-primary-contrast, #fff);border-color:var(--tng-primary, #3f51b5)}.pagination-dots{display:inline-flex;align-items:center;justify-content:center;width:32px;color:var(--tng-text-secondary, #666)}@media(max-width:600px){.tng-table-pagination{justify-content:center;flex-direction:column}.tng-table-toolbar{justify-content:stretch}.tng-table-search{max-width:none}}\n"] }]
418
531
  }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], filterable: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterable", required: false }] }] } });
419
532
 
420
533
  class TngToolbarComponent {
@@ -423,7 +536,7 @@ class TngToolbarComponent {
423
536
  color = input('default', ...(ngDevMode ? [{ debugName: "color" }] : []));
424
537
  elevation = input(true, ...(ngDevMode ? [{ debugName: "elevation" }] : []));
425
538
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
426
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.0", type: TngToolbarComponent, isStandalone: true, selector: "tng-toolbar", inputs: { position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, positionType: { classPropertyName: "positionType", publicName: "positionType", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, elevation: { classPropertyName: "elevation", publicName: "elevation", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.tng-toolbar--top": "position() === \"top\"", "class.tng-toolbar--bottom": "position() === \"bottom\"", "class.tng-toolbar--fixed": "positionType() === \"fixed\"", "class.tng-toolbar--absolute": "positionType() === \"absolute\"", "class.tng-toolbar--relative": "positionType() === \"relative\"", "class.tng-toolbar--static": "positionType() === \"static\"", "class.tng-toolbar--sticky": "positionType() === \"sticky\"", "class.tng-toolbar--primary": "color() === \"primary\"", "class.tng-toolbar--secondary": "color() === \"secondary\"", "class.tng-toolbar--elevated": "elevation()" }, classAttribute: "tng-toolbar" }, ngImport: i0, template: "<div class=\"tng-toolbar__container\">\n <div class=\"tng-toolbar__section tng-toolbar__section--left\">\n <ng-content select=\"[toolbar-left]\"></ng-content>\n </div>\n\n <div class=\"tng-toolbar__section tng-toolbar__section--center\">\n <ng-content select=\"[toolbar-center]\"></ng-content>\n <ng-content></ng-content>\n </div>\n\n <div class=\"tng-toolbar__section tng-toolbar__section--right\">\n <ng-content select=\"[toolbar-right]\"></ng-content>\n </div>\n</div>\n", styles: [".tng-toolbar{display:block;width:100%;background-color:#fff;transition:box-shadow .3s cubic-bezier(.4,0,.2,1)}.tng-toolbar__container{display:flex;align-items:center;justify-content:space-between;padding:0 16px;min-height:64px;max-width:100%;gap:16px}@media(max-width:768px){.tng-toolbar__container{min-height:56px;padding:0 12px;gap:12px}}.tng-toolbar__section{display:flex;align-items:center;gap:12px;flex-shrink:0}.tng-toolbar__section--left{justify-content:flex-start}.tng-toolbar__section--center{justify-content:center;flex:1;overflow:hidden}.tng-toolbar__section--right{justify-content:flex-end}.tng-toolbar--fixed{position:fixed;z-index:1000}.tng-toolbar--absolute{position:absolute;z-index:1000}.tng-toolbar--relative{position:relative}.tng-toolbar--static{position:static}.tng-toolbar--sticky{position:sticky;top:0;z-index:1000}.tng-toolbar--top.tng-toolbar--fixed,.tng-toolbar--top.tng-toolbar--absolute{top:0;left:0;right:0}.tng-toolbar--bottom.tng-toolbar--fixed,.tng-toolbar--bottom.tng-toolbar--absolute{bottom:0;left:0;right:0}.tng-toolbar--elevated{box-shadow:0 2px 4px -1px #0000001a,0 4px 5px #00000012,0 1px 10px #0000000f}.tng-toolbar--primary{background:var(--tng-primary);color:var(--tng-primary-contrast)}.tng-toolbar--secondary{background:var(--tng-secondary);color:var(--tng-secondary-contrast)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
539
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.0", type: TngToolbarComponent, isStandalone: true, selector: "tng-toolbar", inputs: { position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, positionType: { classPropertyName: "positionType", publicName: "positionType", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, elevation: { classPropertyName: "elevation", publicName: "elevation", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.tng-toolbar--top": "position() === \"top\"", "class.tng-toolbar--bottom": "position() === \"bottom\"", "class.tng-toolbar--fixed": "positionType() === \"fixed\"", "class.tng-toolbar--absolute": "positionType() === \"absolute\"", "class.tng-toolbar--relative": "positionType() === \"relative\"", "class.tng-toolbar--static": "positionType() === \"static\"", "class.tng-toolbar--sticky": "positionType() === \"sticky\"", "class.tng-toolbar--primary": "color() === \"primary\"", "class.tng-toolbar--secondary": "color() === \"secondary\"", "class.tng-toolbar--transparent": "color() === \"transparent\"", "class.tng-toolbar--elevated": "elevation()" }, classAttribute: "tng-toolbar" }, ngImport: i0, template: "<div class=\"tng-toolbar__container\">\n <div class=\"tng-toolbar__section tng-toolbar__section--left\">\n <ng-content select=\"[toolbar-left]\"></ng-content>\n </div>\n\n <div class=\"tng-toolbar__section tng-toolbar__section--center\">\n <ng-content select=\"[toolbar-center]\"></ng-content>\n <ng-content></ng-content>\n </div>\n\n <div class=\"tng-toolbar__section tng-toolbar__section--right\">\n <ng-content select=\"[toolbar-right]\"></ng-content>\n </div>\n</div>\n", styles: [".tng-toolbar{display:block;width:100%;background-color:var(--tng-background);transition:box-shadow .3s cubic-bezier(.4,0,.2,1);padding-right:1rem}.tng-toolbar__container{display:flex;align-items:center;justify-content:space-between;padding:0 16px;min-height:64px;max-width:100%;gap:16px}@media(max-width:768px){.tng-toolbar__container{min-height:56px;padding:0 12px;gap:12px}}.tng-toolbar__section{display:flex;align-items:center;gap:12px;flex-shrink:0}.tng-toolbar__section--left{justify-content:flex-start}.tng-toolbar__section--center{justify-content:center;flex:1;overflow:hidden}.tng-toolbar__section--right{justify-content:flex-end}.tng-toolbar--fixed{position:fixed;z-index:1000}.tng-toolbar--absolute{position:absolute;z-index:1000}.tng-toolbar--relative{position:relative}.tng-toolbar--static{position:static}.tng-toolbar--sticky{position:sticky;top:0;z-index:1000}.tng-toolbar--top.tng-toolbar--fixed,.tng-toolbar--top.tng-toolbar--absolute{top:0;left:0;right:0}.tng-toolbar--bottom.tng-toolbar--fixed,.tng-toolbar--bottom.tng-toolbar--absolute{bottom:0;left:0;right:0}.tng-toolbar--elevated{box-shadow:0 2px 4px -1px #0000001a,0 4px 5px #00000012,0 1px 10px #0000000f}.tng-toolbar--primary{background:var(--tng-primary);color:var(--tng-primary-contrast)}.tng-toolbar--secondary{background:var(--tng-secondary);color:var(--tng-secondary-contrast)}.tng-toolbar--transparent{background:transparent;color:var(--tng-primary-contrast);box-shadow:none}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
427
540
  }
428
541
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngToolbarComponent, decorators: [{
429
542
  type: Component,
@@ -438,8 +551,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
438
551
  '[class.tng-toolbar--sticky]': 'positionType() === "sticky"',
439
552
  '[class.tng-toolbar--primary]': 'color() === "primary"',
440
553
  '[class.tng-toolbar--secondary]': 'color() === "secondary"',
554
+ '[class.tng-toolbar--transparent]': 'color() === "transparent"',
441
555
  '[class.tng-toolbar--elevated]': 'elevation()',
442
- }, template: "<div class=\"tng-toolbar__container\">\n <div class=\"tng-toolbar__section tng-toolbar__section--left\">\n <ng-content select=\"[toolbar-left]\"></ng-content>\n </div>\n\n <div class=\"tng-toolbar__section tng-toolbar__section--center\">\n <ng-content select=\"[toolbar-center]\"></ng-content>\n <ng-content></ng-content>\n </div>\n\n <div class=\"tng-toolbar__section tng-toolbar__section--right\">\n <ng-content select=\"[toolbar-right]\"></ng-content>\n </div>\n</div>\n", styles: [".tng-toolbar{display:block;width:100%;background-color:#fff;transition:box-shadow .3s cubic-bezier(.4,0,.2,1)}.tng-toolbar__container{display:flex;align-items:center;justify-content:space-between;padding:0 16px;min-height:64px;max-width:100%;gap:16px}@media(max-width:768px){.tng-toolbar__container{min-height:56px;padding:0 12px;gap:12px}}.tng-toolbar__section{display:flex;align-items:center;gap:12px;flex-shrink:0}.tng-toolbar__section--left{justify-content:flex-start}.tng-toolbar__section--center{justify-content:center;flex:1;overflow:hidden}.tng-toolbar__section--right{justify-content:flex-end}.tng-toolbar--fixed{position:fixed;z-index:1000}.tng-toolbar--absolute{position:absolute;z-index:1000}.tng-toolbar--relative{position:relative}.tng-toolbar--static{position:static}.tng-toolbar--sticky{position:sticky;top:0;z-index:1000}.tng-toolbar--top.tng-toolbar--fixed,.tng-toolbar--top.tng-toolbar--absolute{top:0;left:0;right:0}.tng-toolbar--bottom.tng-toolbar--fixed,.tng-toolbar--bottom.tng-toolbar--absolute{bottom:0;left:0;right:0}.tng-toolbar--elevated{box-shadow:0 2px 4px -1px #0000001a,0 4px 5px #00000012,0 1px 10px #0000000f}.tng-toolbar--primary{background:var(--tng-primary);color:var(--tng-primary-contrast)}.tng-toolbar--secondary{background:var(--tng-secondary);color:var(--tng-secondary-contrast)}\n"] }]
556
+ }, template: "<div class=\"tng-toolbar__container\">\n <div class=\"tng-toolbar__section tng-toolbar__section--left\">\n <ng-content select=\"[toolbar-left]\"></ng-content>\n </div>\n\n <div class=\"tng-toolbar__section tng-toolbar__section--center\">\n <ng-content select=\"[toolbar-center]\"></ng-content>\n <ng-content></ng-content>\n </div>\n\n <div class=\"tng-toolbar__section tng-toolbar__section--right\">\n <ng-content select=\"[toolbar-right]\"></ng-content>\n </div>\n</div>\n", styles: [".tng-toolbar{display:block;width:100%;background-color:var(--tng-background);transition:box-shadow .3s cubic-bezier(.4,0,.2,1);padding-right:1rem}.tng-toolbar__container{display:flex;align-items:center;justify-content:space-between;padding:0 16px;min-height:64px;max-width:100%;gap:16px}@media(max-width:768px){.tng-toolbar__container{min-height:56px;padding:0 12px;gap:12px}}.tng-toolbar__section{display:flex;align-items:center;gap:12px;flex-shrink:0}.tng-toolbar__section--left{justify-content:flex-start}.tng-toolbar__section--center{justify-content:center;flex:1;overflow:hidden}.tng-toolbar__section--right{justify-content:flex-end}.tng-toolbar--fixed{position:fixed;z-index:1000}.tng-toolbar--absolute{position:absolute;z-index:1000}.tng-toolbar--relative{position:relative}.tng-toolbar--static{position:static}.tng-toolbar--sticky{position:sticky;top:0;z-index:1000}.tng-toolbar--top.tng-toolbar--fixed,.tng-toolbar--top.tng-toolbar--absolute{top:0;left:0;right:0}.tng-toolbar--bottom.tng-toolbar--fixed,.tng-toolbar--bottom.tng-toolbar--absolute{bottom:0;left:0;right:0}.tng-toolbar--elevated{box-shadow:0 2px 4px -1px #0000001a,0 4px 5px #00000012,0 1px 10px #0000000f}.tng-toolbar--primary{background:var(--tng-primary);color:var(--tng-primary-contrast)}.tng-toolbar--secondary{background:var(--tng-secondary);color:var(--tng-secondary-contrast)}.tng-toolbar--transparent{background:transparent;color:var(--tng-primary-contrast);box-shadow:none}\n"] }]
443
557
  }], propDecorators: { position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], positionType: [{ type: i0.Input, args: [{ isSignal: true, alias: "positionType", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], elevation: [{ type: i0.Input, args: [{ isSignal: true, alias: "elevation", required: false }] }] } });
444
558
 
445
559
  class TngTabComponent {
@@ -768,6 +882,13 @@ class ThemeService {
768
882
  description: 'Dark mode gradients',
769
883
  primaryColor: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
770
884
  isDark: true
885
+ },
886
+ {
887
+ name: 'futuristic',
888
+ displayName: 'Futuristic',
889
+ description: 'Neon cyberpunk vibes',
890
+ primaryColor: '#00f2ff',
891
+ isDark: true
771
892
  }
772
893
  ];
773
894
  constructor() {
@@ -841,46 +962,26 @@ class TngTooltipComponent {
841
962
  }
842
963
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngTooltipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
843
964
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.0", type: TngTooltipComponent, isStandalone: true, selector: "tng-tooltip", inputs: { content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
844
- <div class="tng-tooltip-container" [@tooltipAnimation]>
965
+ <div class="tng-tooltip-container">
845
966
  @if (isTemplate(content())) {
846
967
  <ng-container *ngTemplateOutlet="$any(content())"></ng-container>
847
968
  } @else {
848
969
  {{ content() }}
849
970
  }
850
971
  </div>
851
- `, isInline: true, styles: [":host{display:block;pointer-events:none;z-index:10000;position:fixed}.tng-tooltip-container{background:#14141ee6;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);color:#fff;padding:8px 12px;border-radius:8px;font-size:14px;font-family:Inter,sans-serif;box-shadow:0 4px 15px #0003;border:1px solid rgba(255,255,255,.1);max-width:250px;word-wrap:break-word;line-height:1.4}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], animations: [
852
- trigger('tooltipAnimation', [
853
- transition(':enter', [
854
- style({ opacity: 0, transform: 'scale(0.9)' }),
855
- animate('150ms cubic-bezier(0.25, 0.8, 0.25, 1)', style({ opacity: 1, transform: 'scale(1)' }))
856
- ]),
857
- transition(':leave', [
858
- animate('100ms ease-out', style({ opacity: 0, transform: 'scale(0.9)' }))
859
- ])
860
- ])
861
- ], changeDetection: i0.ChangeDetectionStrategy.OnPush });
972
+ `, isInline: true, styles: [":host{display:block;pointer-events:none;z-index:10000;position:fixed;animation:tooltipFadeIn .15s cubic-bezier(.25,.8,.25,1) forwards}.tng-tooltip-container{background:#14141ee6;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);color:#fff;padding:8px 12px;border-radius:8px;font-size:14px;font-family:Inter,sans-serif;box-shadow:0 4px 15px #0003;border:1px solid rgba(255,255,255,.1);max-width:250px;word-wrap:break-word;line-height:1.4}@keyframes tooltipFadeIn{0%{opacity:0;transform:scale(.9)}to{opacity:1;transform:scale(1)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
862
973
  }
863
974
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngTooltipComponent, decorators: [{
864
975
  type: Component,
865
976
  args: [{ selector: 'tng-tooltip', standalone: true, imports: [CommonModule], template: `
866
- <div class="tng-tooltip-container" [@tooltipAnimation]>
977
+ <div class="tng-tooltip-container">
867
978
  @if (isTemplate(content())) {
868
979
  <ng-container *ngTemplateOutlet="$any(content())"></ng-container>
869
980
  } @else {
870
981
  {{ content() }}
871
982
  }
872
983
  </div>
873
- `, animations: [
874
- trigger('tooltipAnimation', [
875
- transition(':enter', [
876
- style({ opacity: 0, transform: 'scale(0.9)' }),
877
- animate('150ms cubic-bezier(0.25, 0.8, 0.25, 1)', style({ opacity: 1, transform: 'scale(1)' }))
878
- ]),
879
- transition(':leave', [
880
- animate('100ms ease-out', style({ opacity: 0, transform: 'scale(0.9)' }))
881
- ])
882
- ])
883
- ], changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;pointer-events:none;z-index:10000;position:fixed}.tng-tooltip-container{background:#14141ee6;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);color:#fff;padding:8px 12px;border-radius:8px;font-size:14px;font-family:Inter,sans-serif;box-shadow:0 4px 15px #0003;border:1px solid rgba(255,255,255,.1);max-width:250px;word-wrap:break-word;line-height:1.4}\n"] }]
984
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;pointer-events:none;z-index:10000;position:fixed;animation:tooltipFadeIn .15s cubic-bezier(.25,.8,.25,1) forwards}.tng-tooltip-container{background:#14141ee6;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);color:#fff;padding:8px 12px;border-radius:8px;font-size:14px;font-family:Inter,sans-serif;box-shadow:0 4px 15px #0003;border:1px solid rgba(255,255,255,.1);max-width:250px;word-wrap:break-word;line-height:1.4}@keyframes tooltipFadeIn{0%{opacity:0;transform:scale(.9)}to{opacity:1;transform:scale(1)}}\n"] }]
884
985
  }], propDecorators: { content: [{ type: i0.Input, args: [{ isSignal: true, alias: "content", required: false }] }] } });
885
986
 
886
987
  class TngTooltipDirective {
@@ -1028,37 +1129,15 @@ class TngExpansionPanelComponent {
1028
1129
  this.toggled.emit(newState);
1029
1130
  }
1030
1131
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngExpansionPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1031
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.0", type: TngExpansionPanelComponent, isStandalone: true, selector: "tng-expansion-panel", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, expanded: { classPropertyName: "expanded", publicName: "expanded", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { toggled: "toggled" }, host: { properties: { "class.tng-expansion-panel--expanded": "isExpanded()", "class.tng-expansion-panel--disabled": "disabled()" }, classAttribute: "tng-expansion-panel" }, ngImport: i0, template: "<div class=\"tng-expansion-panel__container\">\n <div \n class=\"tng-expansion-panel__header\" \n (click)=\"toggle()\"\n [class.tng-expansion-panel__header--disabled]=\"disabled()\"\n >\n <h3 class=\"tng-expansion-panel__title\">{{ title() }}</h3>\n <span class=\"tng-expansion-panel__icon material-icons\">\n expand_more\n </span>\n </div>\n\n @if (isExpanded()) {\n <div \n class=\"tng-expansion-panel__content\"\n @expandCollapse\n >\n <div class=\"tng-expansion-panel__body\">\n <ng-content></ng-content>\n </div>\n </div>\n }\n</div>\n", styles: [".tng-expansion-panel{display:block;margin-bottom:12px}.tng-expansion-panel__container{background-color:var(--tng-surface);border:1px solid var(--tng-border);border-radius:8px;overflow:hidden;transition:box-shadow .2s cubic-bezier(.4,0,.2,1)}.tng-expansion-panel__header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;cursor:pointer;-webkit-user-select:none;user-select:none;background-color:var(--tng-background);transition:background-color .2s ease,transform .1s ease}.tng-expansion-panel__header:hover:not(.tng-expansion-panel__header--disabled){background-color:color-mix(in srgb,var(--tng-background),var(--tng-text) 5%)}.tng-expansion-panel__header:active:not(.tng-expansion-panel__header--disabled){transform:scale(.99)}.tng-expansion-panel__header--disabled{cursor:not-allowed;opacity:.6}.tng-expansion-panel__title{margin:0;font-size:1rem;font-weight:500;color:var(--tng-text, #333);line-height:1.5}.tng-expansion-panel__icon{font-size:24px;color:var(--tng-text-secondary, #666);transition:transform .3s cubic-bezier(.4,0,.2,1)}.tng-expansion-panel__content{overflow:hidden}.tng-expansion-panel__body{padding:20px;color:var(--tng-text, #333);line-height:1.6}.tng-expansion-panel--expanded .tng-expansion-panel__container{box-shadow:0 2px 4px #0000001a}.tng-expansion-panel--expanded .tng-expansion-panel__icon{transform:rotate(180deg)}.tng-expansion-panel--disabled{opacity:.6;pointer-events:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], animations: [
1032
- trigger('expandCollapse', [
1033
- transition(':enter', [
1034
- style({ height: '0', opacity: '0', overflow: 'hidden' }),
1035
- animate('300ms cubic-bezier(0.4, 0.0, 0.2, 1)', style({ height: '*', opacity: '1' }))
1036
- ]),
1037
- transition(':leave', [
1038
- style({ height: '*', opacity: '1', overflow: 'hidden' }),
1039
- animate('300ms cubic-bezier(0.4, 0.0, 0.2, 1)', style({ height: '0', opacity: '0' }))
1040
- ])
1041
- ])
1042
- ], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
1132
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.0", type: TngExpansionPanelComponent, isStandalone: true, selector: "tng-expansion-panel", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, expanded: { classPropertyName: "expanded", publicName: "expanded", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { toggled: "toggled" }, host: { properties: { "class.tng-expansion-panel--expanded": "isExpanded()", "class.tng-expansion-panel--disabled": "disabled()" }, classAttribute: "tng-expansion-panel" }, ngImport: i0, template: "<div class=\"tng-expansion-panel__container\">\n <div\n class=\"tng-expansion-panel__header\"\n (click)=\"toggle()\"\n [class.tng-expansion-panel__header--disabled]=\"disabled()\"\n >\n <h3 class=\"tng-expansion-panel__title\">{{ title() }}</h3>\n <span class=\"tng-expansion-panel__icon material-icons\"> expand_more </span>\n </div>\n\n @if (isExpanded()) {\n <div class=\"tng-expansion-panel__content\">\n <div class=\"tng-expansion-panel__body\">\n <ng-content></ng-content>\n </div>\n </div>\n }\n</div>\n", styles: [".tng-expansion-panel{display:block;margin-bottom:12px}.tng-expansion-panel__container{background-color:var(--tng-surface);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid var(--tng-border);border-radius:8px;overflow:hidden;transition:box-shadow .2s cubic-bezier(.4,0,.2,1)}.tng-expansion-panel__header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;cursor:pointer;-webkit-user-select:none;user-select:none;background-color:var(--tng-background);transition:background-color .2s ease,transform .1s ease}.tng-expansion-panel__header:hover:not(.tng-expansion-panel__header--disabled){background-color:color-mix(in srgb,var(--tng-background),var(--tng-text) 5%)}.tng-expansion-panel__header:active:not(.tng-expansion-panel__header--disabled){transform:scale(.99)}.tng-expansion-panel__header--disabled{cursor:not-allowed;opacity:.6}.tng-expansion-panel__title{margin:0;font-size:1rem;font-weight:500;color:var(--tng-text, #333);line-height:1.5}.tng-expansion-panel__icon{font-size:24px;color:var(--tng-text-secondary, #666);transition:transform .3s cubic-bezier(.4,0,.2,1)}.tng-expansion-panel__content{overflow:hidden;animation:expandPanel .3s cubic-bezier(.4,0,.2,1) forwards;transform-origin:top}.tng-expansion-panel__body{padding:20px;color:var(--tng-text, #333);line-height:1.6}@keyframes expandPanel{0%{opacity:0;max-height:0;transform:scaleY(.95)}to{opacity:1;max-height:1000px;transform:scaleY(1)}}.tng-expansion-panel--expanded .tng-expansion-panel__container{box-shadow:0 2px 4px #0000001a}.tng-expansion-panel--expanded .tng-expansion-panel__icon{transform:rotate(180deg)}.tng-expansion-panel--disabled{opacity:.6;pointer-events:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
1043
1133
  }
1044
1134
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngExpansionPanelComponent, decorators: [{
1045
1135
  type: Component,
1046
- args: [{ selector: 'tng-expansion-panel', standalone: true, imports: [CommonModule], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, animations: [
1047
- trigger('expandCollapse', [
1048
- transition(':enter', [
1049
- style({ height: '0', opacity: '0', overflow: 'hidden' }),
1050
- animate('300ms cubic-bezier(0.4, 0.0, 0.2, 1)', style({ height: '*', opacity: '1' }))
1051
- ]),
1052
- transition(':leave', [
1053
- style({ height: '*', opacity: '1', overflow: 'hidden' }),
1054
- animate('300ms cubic-bezier(0.4, 0.0, 0.2, 1)', style({ height: '0', opacity: '0' }))
1055
- ])
1056
- ])
1057
- ], host: {
1136
+ args: [{ selector: 'tng-expansion-panel', standalone: true, imports: [CommonModule], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: {
1058
1137
  'class': 'tng-expansion-panel',
1059
1138
  '[class.tng-expansion-panel--expanded]': 'isExpanded()',
1060
1139
  '[class.tng-expansion-panel--disabled]': 'disabled()'
1061
- }, template: "<div class=\"tng-expansion-panel__container\">\n <div \n class=\"tng-expansion-panel__header\" \n (click)=\"toggle()\"\n [class.tng-expansion-panel__header--disabled]=\"disabled()\"\n >\n <h3 class=\"tng-expansion-panel__title\">{{ title() }}</h3>\n <span class=\"tng-expansion-panel__icon material-icons\">\n expand_more\n </span>\n </div>\n\n @if (isExpanded()) {\n <div \n class=\"tng-expansion-panel__content\"\n @expandCollapse\n >\n <div class=\"tng-expansion-panel__body\">\n <ng-content></ng-content>\n </div>\n </div>\n }\n</div>\n", styles: [".tng-expansion-panel{display:block;margin-bottom:12px}.tng-expansion-panel__container{background-color:var(--tng-surface);border:1px solid var(--tng-border);border-radius:8px;overflow:hidden;transition:box-shadow .2s cubic-bezier(.4,0,.2,1)}.tng-expansion-panel__header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;cursor:pointer;-webkit-user-select:none;user-select:none;background-color:var(--tng-background);transition:background-color .2s ease,transform .1s ease}.tng-expansion-panel__header:hover:not(.tng-expansion-panel__header--disabled){background-color:color-mix(in srgb,var(--tng-background),var(--tng-text) 5%)}.tng-expansion-panel__header:active:not(.tng-expansion-panel__header--disabled){transform:scale(.99)}.tng-expansion-panel__header--disabled{cursor:not-allowed;opacity:.6}.tng-expansion-panel__title{margin:0;font-size:1rem;font-weight:500;color:var(--tng-text, #333);line-height:1.5}.tng-expansion-panel__icon{font-size:24px;color:var(--tng-text-secondary, #666);transition:transform .3s cubic-bezier(.4,0,.2,1)}.tng-expansion-panel__content{overflow:hidden}.tng-expansion-panel__body{padding:20px;color:var(--tng-text, #333);line-height:1.6}.tng-expansion-panel--expanded .tng-expansion-panel__container{box-shadow:0 2px 4px #0000001a}.tng-expansion-panel--expanded .tng-expansion-panel__icon{transform:rotate(180deg)}.tng-expansion-panel--disabled{opacity:.6;pointer-events:none}\n"] }]
1140
+ }, template: "<div class=\"tng-expansion-panel__container\">\n <div\n class=\"tng-expansion-panel__header\"\n (click)=\"toggle()\"\n [class.tng-expansion-panel__header--disabled]=\"disabled()\"\n >\n <h3 class=\"tng-expansion-panel__title\">{{ title() }}</h3>\n <span class=\"tng-expansion-panel__icon material-icons\"> expand_more </span>\n </div>\n\n @if (isExpanded()) {\n <div class=\"tng-expansion-panel__content\">\n <div class=\"tng-expansion-panel__body\">\n <ng-content></ng-content>\n </div>\n </div>\n }\n</div>\n", styles: [".tng-expansion-panel{display:block;margin-bottom:12px}.tng-expansion-panel__container{background-color:var(--tng-surface);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid var(--tng-border);border-radius:8px;overflow:hidden;transition:box-shadow .2s cubic-bezier(.4,0,.2,1)}.tng-expansion-panel__header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;cursor:pointer;-webkit-user-select:none;user-select:none;background-color:var(--tng-background);transition:background-color .2s ease,transform .1s ease}.tng-expansion-panel__header:hover:not(.tng-expansion-panel__header--disabled){background-color:color-mix(in srgb,var(--tng-background),var(--tng-text) 5%)}.tng-expansion-panel__header:active:not(.tng-expansion-panel__header--disabled){transform:scale(.99)}.tng-expansion-panel__header--disabled{cursor:not-allowed;opacity:.6}.tng-expansion-panel__title{margin:0;font-size:1rem;font-weight:500;color:var(--tng-text, #333);line-height:1.5}.tng-expansion-panel__icon{font-size:24px;color:var(--tng-text-secondary, #666);transition:transform .3s cubic-bezier(.4,0,.2,1)}.tng-expansion-panel__content{overflow:hidden;animation:expandPanel .3s cubic-bezier(.4,0,.2,1) forwards;transform-origin:top}.tng-expansion-panel__body{padding:20px;color:var(--tng-text, #333);line-height:1.6}@keyframes expandPanel{0%{opacity:0;max-height:0;transform:scaleY(.95)}to{opacity:1;max-height:1000px;transform:scaleY(1)}}.tng-expansion-panel--expanded .tng-expansion-panel__container{box-shadow:0 2px 4px #0000001a}.tng-expansion-panel--expanded .tng-expansion-panel__icon{transform:rotate(180deg)}.tng-expansion-panel--disabled{opacity:.6;pointer-events:none}\n"] }]
1062
1141
  }], ctorParameters: () => [], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], expanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "expanded", required: false }] }], toggled: [{ type: i0.Output, args: ["toggled"] }] } });
1063
1142
 
1064
1143
  class TngMenuComponent {
@@ -1073,7 +1152,7 @@ class TngMenuComponent {
1073
1152
  [class.tng-menu--comfortable]="density() === 'comfortable'">
1074
1153
  <ng-content></ng-content>
1075
1154
  </nav>
1076
- `, isInline: true, styles: [".tng-menu{display:flex;flex-direction:column;width:100%;padding:8px;background:var(--tng-surface, white)}.tng-menu--horizontal{flex-direction:row;padding:0}.tng-menu--vertical{flex-direction:column}.tng-menu--compact ::ng-deep .tng-menu-item__link{padding-top:8px;padding-bottom:8px;font-size:13px}.tng-menu--comfortable ::ng-deep .tng-menu-item__link{padding-top:12px;padding-bottom:12px;font-size:14px}.tng-menu-group__header{padding:16px 16px 8px;font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:.5px;color:var(--tng-text-secondary, #666)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
1155
+ `, isInline: true, styles: [".tng-menu{display:flex;flex-direction:column;width:100%;padding:8px;background:var(--tng-surface, white);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px)}.tng-menu--horizontal{flex-direction:row;padding:0}.tng-menu--vertical{flex-direction:column}.tng-menu--compact ::ng-deep .tng-menu-item__link{padding-top:8px;padding-bottom:8px;font-size:13px}.tng-menu--comfortable ::ng-deep .tng-menu-item__link{padding-top:12px;padding-bottom:12px;font-size:14px}.tng-menu-group__header{padding:16px 16px 8px;font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:.5px;color:var(--tng-text-secondary, #666)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
1077
1156
  }
1078
1157
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngMenuComponent, decorators: [{
1079
1158
  type: Component,
@@ -1085,7 +1164,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
1085
1164
  [class.tng-menu--comfortable]="density() === 'comfortable'">
1086
1165
  <ng-content></ng-content>
1087
1166
  </nav>
1088
- `, styles: [".tng-menu{display:flex;flex-direction:column;width:100%;padding:8px;background:var(--tng-surface, white)}.tng-menu--horizontal{flex-direction:row;padding:0}.tng-menu--vertical{flex-direction:column}.tng-menu--compact ::ng-deep .tng-menu-item__link{padding-top:8px;padding-bottom:8px;font-size:13px}.tng-menu--comfortable ::ng-deep .tng-menu-item__link{padding-top:12px;padding-bottom:12px;font-size:14px}.tng-menu-group__header{padding:16px 16px 8px;font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:.5px;color:var(--tng-text-secondary, #666)}\n"] }]
1167
+ `, styles: [".tng-menu{display:flex;flex-direction:column;width:100%;padding:8px;background:var(--tng-surface, white);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px)}.tng-menu--horizontal{flex-direction:row;padding:0}.tng-menu--vertical{flex-direction:column}.tng-menu--compact ::ng-deep .tng-menu-item__link{padding-top:8px;padding-bottom:8px;font-size:13px}.tng-menu--comfortable ::ng-deep .tng-menu-item__link{padding-top:12px;padding-bottom:12px;font-size:14px}.tng-menu-group__header{padding:16px 16px 8px;font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:.5px;color:var(--tng-text-secondary, #666)}\n"] }]
1089
1168
  }], propDecorators: { mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], density: [{ type: i0.Input, args: [{ isSignal: true, alias: "density", required: false }] }] } });
1090
1169
 
1091
1170
  class TngMenuItemComponent {
@@ -1138,7 +1217,7 @@ class TngMenuItemComponent {
1138
1217
  (click)="handleClick($event)">
1139
1218
  @if (icon()) {
1140
1219
  <span class="tng-menu-item__icon">
1141
- <span class="material-icons">{{ icon() }}</span>
1220
+ <i [class]="icon()"></i>
1142
1221
  </span>
1143
1222
  }
1144
1223
  <span class="tng-menu-item__label">
@@ -1147,7 +1226,7 @@ class TngMenuItemComponent {
1147
1226
  </span>
1148
1227
  @if (hasChildren()) {
1149
1228
  <span class="tng-menu-item__chevron">
1150
- <span class="material-icons">expand_more</span>
1229
+ <i class="fa fa-chevron-down"></i>
1151
1230
  </span>
1152
1231
  }
1153
1232
  </a>
@@ -1159,7 +1238,7 @@ class TngMenuItemComponent {
1159
1238
  (click)="handleClick($event)">
1160
1239
  @if (icon()) {
1161
1240
  <span class="tng-menu-item__icon">
1162
- <span class="material-icons">{{ icon() }}</span>
1241
+ <i [class]="icon()"></i>
1163
1242
  </span>
1164
1243
  }
1165
1244
  <span class="tng-menu-item__label">
@@ -1168,7 +1247,7 @@ class TngMenuItemComponent {
1168
1247
  </span>
1169
1248
  @if (hasChildren()) {
1170
1249
  <span class="tng-menu-item__chevron">
1171
- <span class="material-icons">expand_more</span>
1250
+ <i class="fa fa-chevron-down"></i>
1172
1251
  </span>
1173
1252
  }
1174
1253
  </button>
@@ -1201,7 +1280,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
1201
1280
  (click)="handleClick($event)">
1202
1281
  @if (icon()) {
1203
1282
  <span class="tng-menu-item__icon">
1204
- <span class="material-icons">{{ icon() }}</span>
1283
+ <i [class]="icon()"></i>
1205
1284
  </span>
1206
1285
  }
1207
1286
  <span class="tng-menu-item__label">
@@ -1210,7 +1289,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
1210
1289
  </span>
1211
1290
  @if (hasChildren()) {
1212
1291
  <span class="tng-menu-item__chevron">
1213
- <span class="material-icons">expand_more</span>
1292
+ <i class="fa fa-chevron-down"></i>
1214
1293
  </span>
1215
1294
  }
1216
1295
  </a>
@@ -1222,7 +1301,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
1222
1301
  (click)="handleClick($event)">
1223
1302
  @if (icon()) {
1224
1303
  <span class="tng-menu-item__icon">
1225
- <span class="material-icons">{{ icon() }}</span>
1304
+ <i [class]="icon()"></i>
1226
1305
  </span>
1227
1306
  }
1228
1307
  <span class="tng-menu-item__label">
@@ -1231,7 +1310,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
1231
1310
  </span>
1232
1311
  @if (hasChildren()) {
1233
1312
  <span class="tng-menu-item__chevron">
1234
- <span class="material-icons">expand_more</span>
1313
+ <i class="fa fa-chevron-down"></i>
1235
1314
  </span>
1236
1315
  }
1237
1316
  </button>
@@ -1274,6 +1353,545 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
1274
1353
  `, styles: [".tng-menu-group{display:block}\n"] }]
1275
1354
  }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }] } });
1276
1355
 
1356
+ /**
1357
+ * TngSidebar - Componente moderno de barra lateral
1358
+ *
1359
+ * Características:
1360
+ * - Totalmente basado en Signals
1361
+ * - Animaciones CSS puras
1362
+ * - Posicionamiento configurable (izquierda/derecha)
1363
+ * - Proyección de contenido
1364
+ * - Responsive y accesible
1365
+ */
1366
+ class TngSidebarComponent {
1367
+ /**
1368
+ * Controla si el sidebar está abierto o cerrado
1369
+ */
1370
+ isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
1371
+ /**
1372
+ * Posición del sidebar: 'left' o 'right'
1373
+ */
1374
+ position = input('left', ...(ngDevMode ? [{ debugName: "position" }] : []));
1375
+ /**
1376
+ * Ancho del sidebar en píxeles
1377
+ */
1378
+ width = input(280, ...(ngDevMode ? [{ debugName: "width" }] : []));
1379
+ /**
1380
+ * Muestra un overlay de fondo cuando está abierto
1381
+ */
1382
+ showOverlay = input(true, ...(ngDevMode ? [{ debugName: "showOverlay" }] : []));
1383
+ /**
1384
+ * Evento emitido cuando el sidebar se cierra
1385
+ */
1386
+ closed = output();
1387
+ /**
1388
+ * Evento emitido cuando el sidebar se abre
1389
+ */
1390
+ opened = output();
1391
+ /**
1392
+ * Alterna el estado del sidebar
1393
+ */
1394
+ toggle() {
1395
+ this.isOpen.set(!this.isOpen());
1396
+ if (this.isOpen()) {
1397
+ this.opened.emit();
1398
+ }
1399
+ else {
1400
+ this.closed.emit();
1401
+ }
1402
+ }
1403
+ /**
1404
+ * Abre el sidebar
1405
+ */
1406
+ open() {
1407
+ if (!this.isOpen()) {
1408
+ this.isOpen.set(true);
1409
+ this.opened.emit();
1410
+ }
1411
+ }
1412
+ /**
1413
+ * Cierra el sidebar
1414
+ */
1415
+ close() {
1416
+ if (this.isOpen()) {
1417
+ this.isOpen.set(false);
1418
+ this.closed.emit();
1419
+ }
1420
+ }
1421
+ /**
1422
+ * Maneja el clic en el overlay para cerrar el sidebar
1423
+ */
1424
+ handleOverlayClick() {
1425
+ this.close();
1426
+ }
1427
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngSidebarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1428
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.0", type: TngSidebarComponent, isStandalone: true, selector: "tng-sidebar", inputs: { position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, showOverlay: { classPropertyName: "showOverlay", publicName: "showOverlay", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed", opened: "opened" }, ngImport: i0, template: "<!-- Overlay de fondo -->\n@if (showOverlay() && isOpen()) {\n <div \n class=\"tng-sidebar-overlay\"\n (click)=\"handleOverlayClick()\"\n ></div>\n}\n\n<!-- Contenedor del Sidebar -->\n<aside \n class=\"tng-sidebar\"\n [class.tng-sidebar--open]=\"isOpen()\"\n [class.tng-sidebar--left]=\"position() === 'left'\"\n [class.tng-sidebar--right]=\"position() === 'right'\"\n [style.width.px]=\"width()\"\n role=\"complementary\"\n [attr.aria-hidden]=\"!isOpen()\"\n>\n <div class=\"tng-sidebar__content\">\n <ng-content></ng-content>\n </div>\n</aside>\n", styles: [".tng-sidebar-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:#00000080;z-index:998;cursor:pointer;opacity:0;animation:fadeIn .3s cubic-bezier(.4,0,.2,1) forwards}.tng-sidebar{position:fixed;top:0;height:100%;background:var(--tng-surface);box-shadow:var(--tng-shadow-md);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);z-index:999;overflow-y:auto;overflow-x:hidden;padding:20px;transition:transform .3s cubic-bezier(.4,0,.2,1)}.tng-sidebar:not(.tng-sidebar--open).tng-sidebar--left{transform:translate(-100%)}.tng-sidebar:not(.tng-sidebar--open).tng-sidebar--right{transform:translate(100%)}.tng-sidebar.tng-sidebar--open{transform:translate(0)}.tng-sidebar.tng-sidebar--left{left:0}.tng-sidebar.tng-sidebar--right{right:0}.tng-sidebar::-webkit-scrollbar{width:6px}.tng-sidebar::-webkit-scrollbar-track{background:#0000000d}.tng-sidebar::-webkit-scrollbar-thumb{background:#0003;border-radius:3px}.tng-sidebar::-webkit-scrollbar-thumb:hover{background:#0000004d}.tng-sidebar__content{padding:1.5rem;min-height:100%}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@media(max-width:768px){.tng-sidebar{max-width:85vw}.tng-sidebar__content{padding:1rem}}@media(prefers-color-scheme:dark){.tng-sidebar{background:#1e1e1e;color:#fff;box-shadow:0 4px 20px #00000080}.tng-sidebar-overlay{background:#000000b3}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
1429
+ }
1430
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngSidebarComponent, decorators: [{
1431
+ type: Component,
1432
+ args: [{ selector: 'tng-sidebar', standalone: true, imports: [CommonModule], template: "<!-- Overlay de fondo -->\n@if (showOverlay() && isOpen()) {\n <div \n class=\"tng-sidebar-overlay\"\n (click)=\"handleOverlayClick()\"\n ></div>\n}\n\n<!-- Contenedor del Sidebar -->\n<aside \n class=\"tng-sidebar\"\n [class.tng-sidebar--open]=\"isOpen()\"\n [class.tng-sidebar--left]=\"position() === 'left'\"\n [class.tng-sidebar--right]=\"position() === 'right'\"\n [style.width.px]=\"width()\"\n role=\"complementary\"\n [attr.aria-hidden]=\"!isOpen()\"\n>\n <div class=\"tng-sidebar__content\">\n <ng-content></ng-content>\n </div>\n</aside>\n", styles: [".tng-sidebar-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:#00000080;z-index:998;cursor:pointer;opacity:0;animation:fadeIn .3s cubic-bezier(.4,0,.2,1) forwards}.tng-sidebar{position:fixed;top:0;height:100%;background:var(--tng-surface);box-shadow:var(--tng-shadow-md);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);z-index:999;overflow-y:auto;overflow-x:hidden;padding:20px;transition:transform .3s cubic-bezier(.4,0,.2,1)}.tng-sidebar:not(.tng-sidebar--open).tng-sidebar--left{transform:translate(-100%)}.tng-sidebar:not(.tng-sidebar--open).tng-sidebar--right{transform:translate(100%)}.tng-sidebar.tng-sidebar--open{transform:translate(0)}.tng-sidebar.tng-sidebar--left{left:0}.tng-sidebar.tng-sidebar--right{right:0}.tng-sidebar::-webkit-scrollbar{width:6px}.tng-sidebar::-webkit-scrollbar-track{background:#0000000d}.tng-sidebar::-webkit-scrollbar-thumb{background:#0003;border-radius:3px}.tng-sidebar::-webkit-scrollbar-thumb:hover{background:#0000004d}.tng-sidebar__content{padding:1.5rem;min-height:100%}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@media(max-width:768px){.tng-sidebar{max-width:85vw}.tng-sidebar__content{padding:1rem}}@media(prefers-color-scheme:dark){.tng-sidebar{background:#1e1e1e;color:#fff;box-shadow:0 4px 20px #00000080}.tng-sidebar-overlay{background:#000000b3}}\n"] }]
1433
+ }], propDecorators: { position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], showOverlay: [{ type: i0.Input, args: [{ isSignal: true, alias: "showOverlay", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }], opened: [{ type: i0.Output, args: ["opened"] }] } });
1434
+
1435
+ class TngSelectPanelComponent {
1436
+ // Inputs
1437
+ options = signal([], ...(ngDevMode ? [{ debugName: "options" }] : []));
1438
+ selectedIndices = signal([], ...(ngDevMode ? [{ debugName: "selectedIndices" }] : []));
1439
+ enableMulti = signal(false, ...(ngDevMode ? [{ debugName: "enableMulti" }] : []));
1440
+ enableSearch = signal(false, ...(ngDevMode ? [{ debugName: "enableSearch" }] : []));
1441
+ searchQuery = signal('', ...(ngDevMode ? [{ debugName: "searchQuery" }] : []));
1442
+ // Outputs
1443
+ optionSelected = output();
1444
+ searchQueryChanged = output();
1445
+ closeRequested = output();
1446
+ onSearchInput(event) {
1447
+ const input = event.target;
1448
+ this.searchQuery.set(input.value);
1449
+ this.searchQueryChanged.emit(input.value);
1450
+ }
1451
+ isSelected(index) {
1452
+ return this.selectedIndices().includes(index);
1453
+ }
1454
+ onOptionClick(index, option) {
1455
+ if (option.disabled) {
1456
+ return;
1457
+ }
1458
+ this.optionSelected.emit(index);
1459
+ }
1460
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngSelectPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1461
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.0", type: TngSelectPanelComponent, isStandalone: true, selector: "tng-select-panel", outputs: { optionSelected: "optionSelected", searchQueryChanged: "searchQueryChanged", closeRequested: "closeRequested" }, ngImport: i0, template: "<div class=\"tng-select-panel\" \n role=\"listbox\"\n [attr.aria-multiselectable]=\"enableMulti()\">\n \n @if (enableSearch()) {\n <div class=\"tng-select-search\">\n <input \n type=\"text\"\n class=\"tng-select-search-input\"\n [value]=\"searchQuery()\"\n (input)=\"onSearchInput($event)\"\n placeholder=\"Search...\"\n aria-label=\"Search options\"\n (click)=\"$event.stopPropagation()\"\n />\n <i class=\"fa fa-search tng-select-search-icon\"></i>\n </div>\n }\n \n <div class=\"tng-select-options\" role=\"list\">\n @if (options().length === 0) {\n <div class=\"tng-select-no-results\">\n No options found\n </div>\n }\n \n @for (option of options(); track $index) {\n <div \n class=\"tng-select-option\"\n [class.selected]=\"isSelected($index)\"\n [class.disabled]=\"option.disabled\"\n role=\"option\"\n [attr.aria-selected]=\"isSelected($index)\"\n [attr.aria-disabled]=\"option.disabled\"\n (click)=\"onOptionClick($index, option)\"\n >\n @if (enableMulti()) {\n <input \n type=\"checkbox\"\n class=\"tng-select-checkbox\"\n [checked]=\"isSelected($index)\"\n [disabled]=\"option.disabled\"\n tabindex=\"-1\"\n />\n }\n <span class=\"tng-select-option-label\">{{ option.label }}</span>\n </div>\n }\n </div>\n</div>\n", styles: [":host{display:block}.tng-select-panel{background:var(--tng-surface, #ffffff);border:1px solid var(--tng-border, #e0e0e0);border-radius:var(--tng-border-radius, 4px);box-shadow:var(--tng-shadow-md, 0 4px 8px rgba(0, 0, 0, .12));overflow:hidden;animation:slideDown .2s cubic-bezier(.4,0,.2,1)}@keyframes slideDown{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}.tng-select-search{position:relative;padding:.75rem;border-bottom:1px solid var(--tng-border, #e0e0e0)}.tng-select-search-input{width:100%;padding:.5rem 2rem .5rem .75rem;border:1px solid var(--tng-border, #e0e0e0);border-radius:var(--tng-border-radius, 4px);font-size:.9rem;color:var(--tng-text, #333);outline:none;transition:border-color .2s ease}.tng-select-search-input:focus{border-color:var(--tng-primary, #00f2ff)}.tng-select-search-icon{position:absolute;right:1.5rem;top:50%;transform:translateY(-50%);color:var(--tng-text-secondary, #757575);pointer-events:none}.tng-select-options{max-height:300px;overflow-y:auto;padding:.25rem 0}.tng-select-options::-webkit-scrollbar{width:8px}.tng-select-options::-webkit-scrollbar-track{background:var(--tng-background, #fafafa)}.tng-select-options::-webkit-scrollbar-thumb{background:var(--tng-border, #e0e0e0);border-radius:4px}.tng-select-options::-webkit-scrollbar-thumb:hover{background:var(--tng-text-secondary, #757575)}.tng-select-option{display:flex;align-items:center;gap:.75rem;padding:.75rem 1rem;cursor:pointer;transition:background-color .15s ease;-webkit-user-select:none;user-select:none}.tng-select-option:hover:not(.disabled){background:var(--tng-background, #fafafa)}.tng-select-option.selected{background:#00f2ff1a;color:var(--tng-primary, #00f2ff)}.tng-select-option.disabled{opacity:.5;cursor:not-allowed}.tng-select-checkbox{appearance:none;-webkit-appearance:none;-moz-appearance:none;width:18px;height:18px;min-width:18px;min-height:18px;border:2px solid var(--tng-border, #999);border-radius:var(--tng-border-radius, 4px);background-color:var(--tng-surface, #ffffff);cursor:pointer;position:relative;transition:all .2s cubic-bezier(.4,0,.2,1);margin:0;pointer-events:none}.tng-select-checkbox:checked{background-color:var(--tng-primary, #00f2ff);border-color:var(--tng-primary, #00f2ff)}.tng-select-checkbox:checked:before{content:\"\";position:absolute;width:4px;height:8px;border:solid var(--tng-primary-contrast, #000000);border-width:0 2px 2px 0;transform:rotate(45deg);top:2px;left:5px}.tng-select-checkbox:disabled{opacity:.5;cursor:not-allowed}.tng-select-option-label{flex:1;font-size:.95rem}.tng-select-no-results{padding:1.5rem 1rem;text-align:center;color:var(--tng-text-secondary, #757575);font-size:.9rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1462
+ }
1463
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngSelectPanelComponent, decorators: [{
1464
+ type: Component,
1465
+ args: [{ selector: 'tng-select-panel', standalone: true, imports: [CommonModule, FormsModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"tng-select-panel\" \n role=\"listbox\"\n [attr.aria-multiselectable]=\"enableMulti()\">\n \n @if (enableSearch()) {\n <div class=\"tng-select-search\">\n <input \n type=\"text\"\n class=\"tng-select-search-input\"\n [value]=\"searchQuery()\"\n (input)=\"onSearchInput($event)\"\n placeholder=\"Search...\"\n aria-label=\"Search options\"\n (click)=\"$event.stopPropagation()\"\n />\n <i class=\"fa fa-search tng-select-search-icon\"></i>\n </div>\n }\n \n <div class=\"tng-select-options\" role=\"list\">\n @if (options().length === 0) {\n <div class=\"tng-select-no-results\">\n No options found\n </div>\n }\n \n @for (option of options(); track $index) {\n <div \n class=\"tng-select-option\"\n [class.selected]=\"isSelected($index)\"\n [class.disabled]=\"option.disabled\"\n role=\"option\"\n [attr.aria-selected]=\"isSelected($index)\"\n [attr.aria-disabled]=\"option.disabled\"\n (click)=\"onOptionClick($index, option)\"\n >\n @if (enableMulti()) {\n <input \n type=\"checkbox\"\n class=\"tng-select-checkbox\"\n [checked]=\"isSelected($index)\"\n [disabled]=\"option.disabled\"\n tabindex=\"-1\"\n />\n }\n <span class=\"tng-select-option-label\">{{ option.label }}</span>\n </div>\n }\n </div>\n</div>\n", styles: [":host{display:block}.tng-select-panel{background:var(--tng-surface, #ffffff);border:1px solid var(--tng-border, #e0e0e0);border-radius:var(--tng-border-radius, 4px);box-shadow:var(--tng-shadow-md, 0 4px 8px rgba(0, 0, 0, .12));overflow:hidden;animation:slideDown .2s cubic-bezier(.4,0,.2,1)}@keyframes slideDown{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}.tng-select-search{position:relative;padding:.75rem;border-bottom:1px solid var(--tng-border, #e0e0e0)}.tng-select-search-input{width:100%;padding:.5rem 2rem .5rem .75rem;border:1px solid var(--tng-border, #e0e0e0);border-radius:var(--tng-border-radius, 4px);font-size:.9rem;color:var(--tng-text, #333);outline:none;transition:border-color .2s ease}.tng-select-search-input:focus{border-color:var(--tng-primary, #00f2ff)}.tng-select-search-icon{position:absolute;right:1.5rem;top:50%;transform:translateY(-50%);color:var(--tng-text-secondary, #757575);pointer-events:none}.tng-select-options{max-height:300px;overflow-y:auto;padding:.25rem 0}.tng-select-options::-webkit-scrollbar{width:8px}.tng-select-options::-webkit-scrollbar-track{background:var(--tng-background, #fafafa)}.tng-select-options::-webkit-scrollbar-thumb{background:var(--tng-border, #e0e0e0);border-radius:4px}.tng-select-options::-webkit-scrollbar-thumb:hover{background:var(--tng-text-secondary, #757575)}.tng-select-option{display:flex;align-items:center;gap:.75rem;padding:.75rem 1rem;cursor:pointer;transition:background-color .15s ease;-webkit-user-select:none;user-select:none}.tng-select-option:hover:not(.disabled){background:var(--tng-background, #fafafa)}.tng-select-option.selected{background:#00f2ff1a;color:var(--tng-primary, #00f2ff)}.tng-select-option.disabled{opacity:.5;cursor:not-allowed}.tng-select-checkbox{appearance:none;-webkit-appearance:none;-moz-appearance:none;width:18px;height:18px;min-width:18px;min-height:18px;border:2px solid var(--tng-border, #999);border-radius:var(--tng-border-radius, 4px);background-color:var(--tng-surface, #ffffff);cursor:pointer;position:relative;transition:all .2s cubic-bezier(.4,0,.2,1);margin:0;pointer-events:none}.tng-select-checkbox:checked{background-color:var(--tng-primary, #00f2ff);border-color:var(--tng-primary, #00f2ff)}.tng-select-checkbox:checked:before{content:\"\";position:absolute;width:4px;height:8px;border:solid var(--tng-primary-contrast, #000000);border-width:0 2px 2px 0;transform:rotate(45deg);top:2px;left:5px}.tng-select-checkbox:disabled{opacity:.5;cursor:not-allowed}.tng-select-option-label{flex:1;font-size:.95rem}.tng-select-no-results{padding:1.5rem 1rem;text-align:center;color:var(--tng-text-secondary, #757575);font-size:.9rem}\n"] }]
1466
+ }], propDecorators: { optionSelected: [{ type: i0.Output, args: ["optionSelected"] }], searchQueryChanged: [{ type: i0.Output, args: ["searchQueryChanged"] }], closeRequested: [{ type: i0.Output, args: ["closeRequested"] }] } });
1467
+
1468
+ class TngSelectDirective {
1469
+ el = inject((ElementRef));
1470
+ viewContainerRef = inject(ViewContainerRef);
1471
+ ngControl = inject(NgControl, { optional: true, self: true });
1472
+ // Inputs
1473
+ enableMulti = input(false, ...(ngDevMode ? [{ debugName: "enableMulti" }] : []));
1474
+ // Support native multiple attribute
1475
+ multiple = input(false, ...(ngDevMode ? [{ debugName: "multiple", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
1476
+ enableSearch = input(false, ...(ngDevMode ? [{ debugName: "enableSearch" }] : []));
1477
+ placeholder = input('Select an option', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
1478
+ customTrigger = input(false, ...(ngDevMode ? [{ debugName: "customTrigger" }] : []));
1479
+ triggerRef = input(undefined, ...(ngDevMode ? [{ debugName: "triggerRef" }] : []));
1480
+ // Model for two-way binding
1481
+ selectedValues = model([], ...(ngDevMode ? [{ debugName: "selectedValues" }] : []));
1482
+ // State signals
1483
+ isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
1484
+ searchQuery = signal('', ...(ngDevMode ? [{ debugName: "searchQuery" }] : []));
1485
+ _options = signal([], ...(ngDevMode ? [{ debugName: "_options" }] : []));
1486
+ _selectedIndices = signal([], ...(ngDevMode ? [{ debugName: "_selectedIndices" }] : []));
1487
+ // Component reference for the panel
1488
+ panelRef = null;
1489
+ // Generated trigger element
1490
+ triggerEl = null;
1491
+ // Computed
1492
+ isMulti = computed(() => this.enableMulti() || this.multiple(), ...(ngDevMode ? [{ debugName: "isMulti" }] : []));
1493
+ options = computed(() => this._options(), ...(ngDevMode ? [{ debugName: "options" }] : []));
1494
+ filteredOptions = computed(() => {
1495
+ const query = this.searchQuery().toLowerCase();
1496
+ const opts = this._options();
1497
+ if (!query || !this.enableSearch()) {
1498
+ return opts;
1499
+ }
1500
+ return opts.filter(opt => opt.label.toLowerCase().includes(query));
1501
+ }, ...(ngDevMode ? [{ debugName: "filteredOptions" }] : []));
1502
+ selectedOptions = computed(() => {
1503
+ const indices = this._selectedIndices();
1504
+ const opts = this._options();
1505
+ return indices.map(idx => opts[idx]).filter(Boolean);
1506
+ }, ...(ngDevMode ? [{ debugName: "selectedOptions" }] : []));
1507
+ displayText = computed(() => {
1508
+ const selected = this.selectedOptions();
1509
+ if (selected.length === 0) {
1510
+ return this.placeholder();
1511
+ }
1512
+ return selected.map(opt => opt.label).join(', ');
1513
+ }, ...(ngDevMode ? [{ debugName: "displayText" }] : []));
1514
+ constructor() {
1515
+ // Sync selected values with model
1516
+ effect(() => {
1517
+ const selected = this.selectedOptions();
1518
+ this.selectedValues.set(selected.map(opt => opt.value));
1519
+ });
1520
+ // Update form control value
1521
+ effect(() => {
1522
+ if (this.ngControl?.control) {
1523
+ const values = this.selectedValues();
1524
+ const newValue = this.isMulti() ? values : (values[0] ?? null);
1525
+ this.ngControl.control.setValue(newValue, { emitEvent: false });
1526
+ }
1527
+ });
1528
+ // Update generated trigger text
1529
+ effect(() => {
1530
+ if (this.triggerEl) {
1531
+ const textSpan = this.triggerEl.querySelector('.tng-select-trigger-text');
1532
+ if (textSpan) {
1533
+ textSpan.textContent = this.displayText();
1534
+ }
1535
+ }
1536
+ });
1537
+ }
1538
+ ngAfterViewInit() {
1539
+ this.loadOptionsFromSelect();
1540
+ this.loadInitialSelection();
1541
+ // Hide the native select visually but keep it in the DOM for forms
1542
+ this.el.nativeElement.style.position = 'absolute';
1543
+ this.el.nativeElement.style.opacity = '0';
1544
+ this.el.nativeElement.style.pointerEvents = 'none';
1545
+ this.el.nativeElement.style.height = '0';
1546
+ this.el.nativeElement.style.width = '0';
1547
+ if (!this.customTrigger()) {
1548
+ this.createTrigger();
1549
+ }
1550
+ }
1551
+ ngOnDestroy() {
1552
+ this.closePanel();
1553
+ if (this.triggerEl) {
1554
+ this.triggerEl.remove();
1555
+ }
1556
+ }
1557
+ onClick(event) {
1558
+ // If we have a generated trigger, the click is handled there.
1559
+ // If we have a custom trigger (parent component), it handles the click.
1560
+ // But if the user somehow clicks the hidden select (label for?), we should toggle.
1561
+ event.preventDefault();
1562
+ event.stopPropagation();
1563
+ this.togglePanel();
1564
+ }
1565
+ onKeyDown(event) {
1566
+ if (event.key === 'Enter' || event.key === ' ') {
1567
+ event.preventDefault();
1568
+ this.togglePanel();
1569
+ }
1570
+ else if (event.key === 'Escape') {
1571
+ this.closePanel();
1572
+ }
1573
+ }
1574
+ createTrigger() {
1575
+ const trigger = document.createElement('div');
1576
+ trigger.className = 'tng-select-trigger';
1577
+ trigger.style.display = 'flex';
1578
+ trigger.style.alignItems = 'center';
1579
+ trigger.style.justifyContent = 'space-between';
1580
+ trigger.style.padding = '0.75rem 1rem';
1581
+ trigger.style.border = '1px solid #ccc';
1582
+ trigger.style.borderRadius = '4px';
1583
+ trigger.style.background = '#fff';
1584
+ trigger.style.cursor = 'pointer';
1585
+ trigger.style.minHeight = '48px';
1586
+ trigger.style.boxSizing = 'border-box';
1587
+ const text = document.createElement('span');
1588
+ text.className = 'tng-select-trigger-text';
1589
+ text.textContent = this.displayText();
1590
+ text.style.flex = '1';
1591
+ text.style.overflow = 'hidden';
1592
+ text.style.textOverflow = 'ellipsis';
1593
+ text.style.whiteSpace = 'nowrap';
1594
+ const arrow = document.createElement('span');
1595
+ arrow.innerHTML = '&#9662;'; // Down arrow
1596
+ arrow.style.marginLeft = '0.5rem';
1597
+ trigger.appendChild(text);
1598
+ trigger.appendChild(arrow);
1599
+ trigger.addEventListener('click', (e) => {
1600
+ e.preventDefault();
1601
+ e.stopPropagation();
1602
+ this.togglePanel();
1603
+ });
1604
+ // Insert after select
1605
+ const parent = this.el.nativeElement.parentNode;
1606
+ if (parent) {
1607
+ parent.insertBefore(trigger, this.el.nativeElement.nextSibling);
1608
+ }
1609
+ this.triggerEl = trigger;
1610
+ }
1611
+ loadOptionsFromSelect() {
1612
+ const selectEl = this.el.nativeElement;
1613
+ const options = [];
1614
+ for (let i = 0; i < selectEl.options.length; i++) {
1615
+ const option = selectEl.options[i];
1616
+ options.push({
1617
+ value: option.value,
1618
+ label: option.text,
1619
+ disabled: option.disabled
1620
+ });
1621
+ }
1622
+ this._options.set(options);
1623
+ }
1624
+ loadInitialSelection() {
1625
+ const selectEl = this.el.nativeElement;
1626
+ const selectedIndices = [];
1627
+ if (this.isMulti()) {
1628
+ for (let i = 0; i < selectEl.options.length; i++) {
1629
+ if (selectEl.options[i].selected) {
1630
+ selectedIndices.push(i);
1631
+ }
1632
+ }
1633
+ }
1634
+ else {
1635
+ if (selectEl.selectedIndex >= 0) {
1636
+ selectedIndices.push(selectEl.selectedIndex);
1637
+ }
1638
+ }
1639
+ this._selectedIndices.set(selectedIndices);
1640
+ }
1641
+ togglePanel() {
1642
+ if (this.isOpen()) {
1643
+ this.closePanel();
1644
+ }
1645
+ else {
1646
+ this.openPanel();
1647
+ }
1648
+ }
1649
+ openPanel() {
1650
+ if (this.panelRef) {
1651
+ return;
1652
+ }
1653
+ this.isOpen.set(true);
1654
+ // Create the panel component
1655
+ this.panelRef = this.viewContainerRef.createComponent(TngSelectPanelComponent);
1656
+ // Configure the panel
1657
+ this.panelRef.instance.options.set(this.filteredOptions());
1658
+ this.panelRef.instance.selectedIndices.set(this._selectedIndices());
1659
+ this.panelRef.instance.enableMulti.set(this.isMulti());
1660
+ this.panelRef.instance.enableSearch.set(this.enableSearch());
1661
+ this.panelRef.instance.searchQuery.set(this.searchQuery());
1662
+ // Position the panel
1663
+ this.positionPanel();
1664
+ // Listen to panel events
1665
+ const sub1 = this.panelRef.instance.optionSelected.subscribe((index) => {
1666
+ this.onOptionSelected(index);
1667
+ });
1668
+ const sub2 = this.panelRef.instance.searchQueryChanged.subscribe((query) => {
1669
+ this.searchQuery.set(query);
1670
+ // Update filtered options in the panel
1671
+ this.panelRef.instance.options.set(this.filteredOptions());
1672
+ });
1673
+ const sub3 = this.panelRef.instance.closeRequested.subscribe(() => {
1674
+ this.closePanel();
1675
+ });
1676
+ // Store subscriptions for cleanup
1677
+ this.panelRef.instance._subscriptions = [sub1, sub2, sub3];
1678
+ // Add click outside listener
1679
+ setTimeout(() => {
1680
+ document.addEventListener('click', this.onDocumentClick);
1681
+ }, 0);
1682
+ }
1683
+ closePanel() {
1684
+ if (!this.panelRef) {
1685
+ return;
1686
+ }
1687
+ this.isOpen.set(false);
1688
+ // Cleanup subscriptions
1689
+ const subs = this.panelRef.instance._subscriptions || [];
1690
+ subs.forEach((sub) => sub.unsubscribe());
1691
+ // Destroy the panel
1692
+ this.panelRef.destroy();
1693
+ this.panelRef = null;
1694
+ // Remove click outside listener
1695
+ document.removeEventListener('click', this.onDocumentClick);
1696
+ // Reset search
1697
+ this.searchQuery.set('');
1698
+ }
1699
+ positionPanel() {
1700
+ if (!this.panelRef) {
1701
+ return;
1702
+ }
1703
+ // Use provided trigger ref, or generated trigger, or fallback to select element
1704
+ const anchor = this.triggerRef() || this.triggerEl || this.el.nativeElement;
1705
+ const panelEl = this.panelRef.location.nativeElement;
1706
+ // Calculate position relative to offset parent to support scrolling
1707
+ const offsetParent = anchor.offsetParent || document.body;
1708
+ const anchorRect = anchor.getBoundingClientRect();
1709
+ const parentRect = offsetParent.getBoundingClientRect();
1710
+ const top = anchorRect.bottom - parentRect.top;
1711
+ const left = anchorRect.left - parentRect.left;
1712
+ panelEl.style.position = 'absolute';
1713
+ panelEl.style.top = `${top + 4}px`;
1714
+ panelEl.style.left = `${left}px`;
1715
+ panelEl.style.width = `${anchorRect.width}px`;
1716
+ panelEl.style.zIndex = '1000';
1717
+ }
1718
+ onOptionSelected(index) {
1719
+ const currentIndices = [...this._selectedIndices()];
1720
+ if (this.isMulti()) {
1721
+ // Toggle selection in multi mode
1722
+ const idx = currentIndices.indexOf(index);
1723
+ if (idx >= 0) {
1724
+ currentIndices.splice(idx, 1);
1725
+ }
1726
+ else {
1727
+ currentIndices.push(index);
1728
+ }
1729
+ this._selectedIndices.set(currentIndices);
1730
+ // Update panel selection
1731
+ if (this.panelRef) {
1732
+ this.panelRef.instance.selectedIndices.set(currentIndices);
1733
+ }
1734
+ }
1735
+ else {
1736
+ // Single selection mode
1737
+ this._selectedIndices.set([index]);
1738
+ this.closePanel();
1739
+ }
1740
+ // Update native select
1741
+ this.updateNativeSelect();
1742
+ }
1743
+ updateNativeSelect() {
1744
+ const selectEl = this.el.nativeElement;
1745
+ const selectedIndices = this._selectedIndices();
1746
+ // Clear all selections
1747
+ for (let i = 0; i < selectEl.options.length; i++) {
1748
+ selectEl.options[i].selected = false;
1749
+ }
1750
+ // Set new selections
1751
+ selectedIndices.forEach(idx => {
1752
+ if (selectEl.options[idx]) {
1753
+ selectEl.options[idx].selected = true;
1754
+ }
1755
+ });
1756
+ // Trigger change event
1757
+ selectEl.dispatchEvent(new Event('change', { bubbles: true }));
1758
+ // Also trigger input event for some frameworks
1759
+ selectEl.dispatchEvent(new Event('input', { bubbles: true }));
1760
+ }
1761
+ onDocumentClick = (event) => {
1762
+ const target = event.target;
1763
+ const selectEl = this.el.nativeElement;
1764
+ const panelEl = this.panelRef?.location.nativeElement;
1765
+ const triggerEl = this.triggerEl;
1766
+ const triggerRef = this.triggerRef();
1767
+ if (!selectEl.contains(target) &&
1768
+ !panelEl?.contains(target) &&
1769
+ !triggerEl?.contains(target) &&
1770
+ !triggerRef?.contains(target)) {
1771
+ this.closePanel();
1772
+ }
1773
+ };
1774
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngSelectDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1775
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.0", type: TngSelectDirective, isStandalone: true, selector: "select[tngSelect]", inputs: { enableMulti: { classPropertyName: "enableMulti", publicName: "enableMulti", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, enableSearch: { classPropertyName: "enableSearch", publicName: "enableSearch", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, customTrigger: { classPropertyName: "customTrigger", publicName: "customTrigger", isSignal: true, isRequired: false, transformFunction: null }, triggerRef: { classPropertyName: "triggerRef", publicName: "triggerRef", isSignal: true, isRequired: false, transformFunction: null }, selectedValues: { classPropertyName: "selectedValues", publicName: "selectedValues", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedValues: "selectedValuesChange" }, host: { listeners: { "click": "onClick($event)", "keydown": "onKeyDown($event)" }, properties: { "class.tng-select": "true", "class.tng-select-multi": "isMulti()", "class.tng-select-search": "enableSearch()", "class.tng-select-open": "isOpen()", "attr.aria-expanded": "isOpen()", "attr.aria-haspopup": "\"listbox\"", "attr.aria-multiselectable": "isMulti()" } }, ngImport: i0 });
1776
+ }
1777
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngSelectDirective, decorators: [{
1778
+ type: Directive,
1779
+ args: [{
1780
+ selector: 'select[tngSelect]',
1781
+ standalone: true,
1782
+ host: {
1783
+ '[class.tng-select]': 'true',
1784
+ '[class.tng-select-multi]': 'isMulti()',
1785
+ '[class.tng-select-search]': 'enableSearch()',
1786
+ '[class.tng-select-open]': 'isOpen()',
1787
+ '[attr.aria-expanded]': 'isOpen()',
1788
+ '[attr.aria-haspopup]': '"listbox"',
1789
+ '[attr.aria-multiselectable]': 'isMulti()'
1790
+ }
1791
+ }]
1792
+ }], ctorParameters: () => [], propDecorators: { enableMulti: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableMulti", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], enableSearch: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableSearch", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], customTrigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "customTrigger", required: false }] }], triggerRef: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerRef", required: false }] }], selectedValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedValues", required: false }] }, { type: i0.Output, args: ["selectedValuesChange"] }], onClick: [{
1793
+ type: HostListener,
1794
+ args: ['click', ['$event']]
1795
+ }], onKeyDown: [{
1796
+ type: HostListener,
1797
+ args: ['keydown', ['$event']]
1798
+ }] } });
1799
+
1800
+ class TngSelectComponent {
1801
+ // Inputs
1802
+ label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
1803
+ options = input.required(...(ngDevMode ? [{ debugName: "options" }] : []));
1804
+ enableMulti = input(false, ...(ngDevMode ? [{ debugName: "enableMulti" }] : []));
1805
+ enableSearch = input(false, ...(ngDevMode ? [{ debugName: "enableSearch" }] : []));
1806
+ placeholder = input('Select an option', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
1807
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
1808
+ hint = input('', ...(ngDevMode ? [{ debugName: "hint" }] : []));
1809
+ ariaLabel = input('', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
1810
+ // Model for two-way binding
1811
+ value = model([], ...(ngDevMode ? [{ debugName: "value" }] : []));
1812
+ // Internal state
1813
+ cvaDisabled = signal(false, ...(ngDevMode ? [{ debugName: "cvaDisabled" }] : []));
1814
+ // ViewChild
1815
+ selectDirective = viewChild(TngSelectDirective, ...(ngDevMode ? [{ debugName: "selectDirective" }] : []));
1816
+ // Computed
1817
+ selectId = computed(() => `tng-select-${Math.random().toString(36).substr(2, 9)}`, ...(ngDevMode ? [{ debugName: "selectId" }] : []));
1818
+ effectiveDisabled = computed(() => this.disabled() || this.cvaDisabled(), ...(ngDevMode ? [{ debugName: "effectiveDisabled" }] : []));
1819
+ displayText = computed(() => {
1820
+ const values = this.value();
1821
+ const opts = this.options();
1822
+ if (!values || values.length === 0) {
1823
+ return this.placeholder();
1824
+ }
1825
+ const selectedOpts = opts.filter(opt => values.includes(opt.value));
1826
+ return selectedOpts.map(opt => opt.label).join(', ');
1827
+ }, ...(ngDevMode ? [{ debugName: "displayText" }] : []));
1828
+ // CVA callbacks
1829
+ onChange = () => { };
1830
+ onTouched = () => { };
1831
+ constructor() {
1832
+ // Sync model changes to CVA
1833
+ effect(() => {
1834
+ const val = this.value();
1835
+ // Avoid circular updates if possible, but for now just emit
1836
+ if (this.enableMulti()) {
1837
+ this.onChange(val);
1838
+ }
1839
+ else {
1840
+ this.onChange(val.length > 0 ? val[0] : null);
1841
+ }
1842
+ this.onTouched();
1843
+ });
1844
+ }
1845
+ onDisplayClick(event) {
1846
+ if (this.effectiveDisabled())
1847
+ return;
1848
+ event.preventDefault();
1849
+ event.stopPropagation();
1850
+ this.selectDirective()?.togglePanel();
1851
+ }
1852
+ // ControlValueAccessor implementation
1853
+ writeValue(obj) {
1854
+ if (obj !== null && obj !== undefined) {
1855
+ if (Array.isArray(obj)) {
1856
+ this.value.set(obj);
1857
+ }
1858
+ else {
1859
+ this.value.set([obj]);
1860
+ }
1861
+ }
1862
+ else {
1863
+ this.value.set([]);
1864
+ }
1865
+ }
1866
+ registerOnChange(fn) {
1867
+ this.onChange = fn;
1868
+ }
1869
+ registerOnTouched(fn) {
1870
+ this.onTouched = fn;
1871
+ }
1872
+ setDisabledState(isDisabled) {
1873
+ this.cvaDisabled.set(isDisabled);
1874
+ }
1875
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1876
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.0", type: TngSelectComponent, isStandalone: true, selector: "tng-select", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, enableMulti: { classPropertyName: "enableMulti", publicName: "enableMulti", isSignal: true, isRequired: false, transformFunction: null }, enableSearch: { classPropertyName: "enableSearch", publicName: "enableSearch", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, providers: [
1877
+ {
1878
+ provide: NG_VALUE_ACCESSOR,
1879
+ useExisting: forwardRef(() => TngSelectComponent),
1880
+ multi: true
1881
+ }
1882
+ ], viewQueries: [{ propertyName: "selectDirective", first: true, predicate: TngSelectDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"tng-select-wrapper\" [class.tng-select-open]=\"selectDirective()?.isOpen()\">\n @if (label()) {\n <label class=\"tng-select-label\" [attr.for]=\"selectId()\">\n {{ label() }}\n </label>\n }\n\n <div class=\"tng-select-container\">\n <select\n [id]=\"selectId()\"\n tngSelect\n [enableMulti]=\"enableMulti()\"\n [enableSearch]=\"enableSearch()\"\n [placeholder]=\"placeholder()\"\n [customTrigger]=\"true\"\n [multiple]=\"enableMulti()\"\n [triggerRef]=\"triggerDisplay\"\n [(selectedValues)]=\"value\"\n [disabled]=\"effectiveDisabled()\"\n [attr.aria-label]=\"ariaLabel() || label()\"\n >\n @for (option of options(); track option.value) {\n <option [value]=\"option.value\" [disabled]=\"option.disabled\">\n {{ option.label }}\n </option>\n }\n </select>\n\n <div\n class=\"tng-select-display\"\n #triggerDisplay\n [class.disabled]=\"effectiveDisabled()\"\n (click)=\"onDisplayClick($event)\"\n >\n <span class=\"tng-select-display-text\">\n {{ displayText() }}\n </span>\n <i class=\"fa fa-chevron-down tng-select-arrow\"></i>\n </div>\n </div>\n\n @if (hint()) {\n <div class=\"tng-select-hint\">\n {{ hint() }}\n </div>\n }\n</div>\n", styles: [":host{display:block;margin-bottom:1.5rem;font-family:var(--tng-font-family, \"Inter\", sans-serif)}.tng-select-wrapper{width:100%}.tng-select-label{display:block;margin-bottom:.5rem;font-size:.9rem;font-weight:500;color:var(--tng-text, #333)}.tng-select-container{position:relative}.tng-select-display{display:flex;align-items:center;justify-content:space-between;gap:.75rem;padding:.75rem 1rem;border:1px solid var(--tng-border, #999);border-radius:var(--tng-border-radius, 4px);background:var(--tng-surface, #ffffff);cursor:pointer;transition:all .2s ease;min-height:48px}.tng-select-display:hover:not(.disabled){border-color:var(--tng-text-secondary, #757575)}.tng-select-display.disabled{opacity:.6;cursor:not-allowed;background:var(--tng-background, #fafafa)}.tng-select-wrapper.tng-select-open .tng-select-display{border-color:var(--tng-primary, #00f2ff);border-width:2px;padding:calc(.75rem - 1px) calc(1rem - 1px)}.tng-select-display-text{flex:1;color:var(--tng-text, #333);font-size:1rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tng-select-display-text:empty:before{content:attr(data-placeholder);color:var(--tng-text-secondary, #757575)}.tng-select-arrow{color:var(--tng-text-secondary, #757575);transition:transform .2s ease;font-size:.8rem}.tng-select-wrapper.tng-select-open .tng-select-arrow{transform:rotate(180deg)}.tng-select-hint{margin-top:.25rem;font-size:.85rem;color:var(--tng-text-secondary, #757575)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: TngSelectDirective, selector: "select[tngSelect]", inputs: ["enableMulti", "multiple", "enableSearch", "placeholder", "customTrigger", "triggerRef", "selectedValues"], outputs: ["selectedValuesChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1883
+ }
1884
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngSelectComponent, decorators: [{
1885
+ type: Component,
1886
+ args: [{ selector: 'tng-select', standalone: true, imports: [CommonModule, FormsModule, TngSelectDirective], providers: [
1887
+ {
1888
+ provide: NG_VALUE_ACCESSOR,
1889
+ useExisting: forwardRef(() => TngSelectComponent),
1890
+ multi: true
1891
+ }
1892
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"tng-select-wrapper\" [class.tng-select-open]=\"selectDirective()?.isOpen()\">\n @if (label()) {\n <label class=\"tng-select-label\" [attr.for]=\"selectId()\">\n {{ label() }}\n </label>\n }\n\n <div class=\"tng-select-container\">\n <select\n [id]=\"selectId()\"\n tngSelect\n [enableMulti]=\"enableMulti()\"\n [enableSearch]=\"enableSearch()\"\n [placeholder]=\"placeholder()\"\n [customTrigger]=\"true\"\n [multiple]=\"enableMulti()\"\n [triggerRef]=\"triggerDisplay\"\n [(selectedValues)]=\"value\"\n [disabled]=\"effectiveDisabled()\"\n [attr.aria-label]=\"ariaLabel() || label()\"\n >\n @for (option of options(); track option.value) {\n <option [value]=\"option.value\" [disabled]=\"option.disabled\">\n {{ option.label }}\n </option>\n }\n </select>\n\n <div\n class=\"tng-select-display\"\n #triggerDisplay\n [class.disabled]=\"effectiveDisabled()\"\n (click)=\"onDisplayClick($event)\"\n >\n <span class=\"tng-select-display-text\">\n {{ displayText() }}\n </span>\n <i class=\"fa fa-chevron-down tng-select-arrow\"></i>\n </div>\n </div>\n\n @if (hint()) {\n <div class=\"tng-select-hint\">\n {{ hint() }}\n </div>\n }\n</div>\n", styles: [":host{display:block;margin-bottom:1.5rem;font-family:var(--tng-font-family, \"Inter\", sans-serif)}.tng-select-wrapper{width:100%}.tng-select-label{display:block;margin-bottom:.5rem;font-size:.9rem;font-weight:500;color:var(--tng-text, #333)}.tng-select-container{position:relative}.tng-select-display{display:flex;align-items:center;justify-content:space-between;gap:.75rem;padding:.75rem 1rem;border:1px solid var(--tng-border, #999);border-radius:var(--tng-border-radius, 4px);background:var(--tng-surface, #ffffff);cursor:pointer;transition:all .2s ease;min-height:48px}.tng-select-display:hover:not(.disabled){border-color:var(--tng-text-secondary, #757575)}.tng-select-display.disabled{opacity:.6;cursor:not-allowed;background:var(--tng-background, #fafafa)}.tng-select-wrapper.tng-select-open .tng-select-display{border-color:var(--tng-primary, #00f2ff);border-width:2px;padding:calc(.75rem - 1px) calc(1rem - 1px)}.tng-select-display-text{flex:1;color:var(--tng-text, #333);font-size:1rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tng-select-display-text:empty:before{content:attr(data-placeholder);color:var(--tng-text-secondary, #757575)}.tng-select-arrow{color:var(--tng-text-secondary, #757575);transition:transform .2s ease;font-size:.8rem}.tng-select-wrapper.tng-select-open .tng-select-arrow{transform:rotate(180deg)}.tng-select-hint{margin-top:.25rem;font-size:.85rem;color:var(--tng-text-secondary, #757575)}\n"] }]
1893
+ }], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], enableMulti: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableMulti", required: false }] }], enableSearch: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableSearch", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], selectDirective: [{ type: i0.ViewChild, args: [i0.forwardRef(() => TngSelectDirective), { isSignal: true }] }] } });
1894
+
1277
1895
  /*
1278
1896
  * Public API Surface of tecnualng
1279
1897
  */
@@ -1282,5 +1900,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
1282
1900
  * Generated bundle index. Do not edit.
1283
1901
  */
1284
1902
 
1285
- export { TecnualDatepickerComponent, TecnualInputComponent, TecnualTableComponent, ThemeService, TngButton, TngCardComponent, TngExpansionPanelComponent, TngMenuComponent, TngMenuGroupComponent, TngMenuItemComponent, TngTabComponent, TngTabsComponent, TngToolbarComponent, TngTooltipComponent, TngTooltipDirective };
1903
+ export { TecnualDatepickerComponent, TecnualInputComponent, TecnualTableComponent, ThemeService, TngButton, TngCardComponent, TngExpansionPanelComponent, TngFormFieldComponent, TngInputDirective, TngMenuComponent, TngMenuGroupComponent, TngMenuItemComponent, TngSelectComponent, TngSelectDirective, TngSelectPanelComponent, TngSidebarComponent, TngTabComponent, TngTabsComponent, TngToolbarComponent, TngTooltipComponent, TngTooltipDirective };
1286
1904
  //# sourceMappingURL=tecnualng.mjs.map