tecnualng 0.0.1 → 21.0.11

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,8 +1,11 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, ChangeDetectionStrategy, ViewEncapsulation, Component, model, forwardRef, signal, computed, HostListener, effect, Injectable } from '@angular/core';
2
+ import { input, ChangeDetectionStrategy, ViewEncapsulation, Component, model, forwardRef, signal, computed, HostListener, effect, Injectable, TemplateRef, createComponent, Input, Directive, output, ContentChildren } from '@angular/core';
3
3
  import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
4
4
  import * as i1 from '@angular/common';
5
5
  import { CommonModule } from '@angular/common';
6
+ import { trigger, transition, style, animate } from '@angular/animations';
7
+ import * as i1$1 from '@angular/router';
8
+ import { RouterModule } from '@angular/router';
6
9
 
7
10
  class TngButton {
8
11
  variant = input(null, ...(ngDevMode ? [{ debugName: "variant" }] : []));
@@ -30,7 +33,7 @@ class TngButton {
30
33
  button.appendChild(circle);
31
34
  }
32
35
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngButton, deps: [], target: i0.ɵɵFactoryTarget.Component });
33
- 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;-webkit-appearance:none;overflow:hidden;vertical-align:middle;background:transparent;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-color:var(--tng-primary);color:var(--tng-primary-contrast)}.tng-button--primary:hover{background-color:color-mix(in srgb,var(--tng-primary),white 10%)}.tng-button--secondary{background-color:var(--tng-secondary);color:var(--tng-secondary-contrast)}.tng-button--secondary:hover{background-color:color-mix(in srgb,var(--tng-secondary),white 10%)}.tng-button--success{background-color:var(--tng-success);color:#fff}.tng-button--success:hover{background-color:color-mix(in srgb,var(--tng-success),white 10%)}.tng-button--warning{background-color:var(--tng-warning);color:#fff}.tng-button--warning:hover{background-color:color-mix(in srgb,var(--tng-warning),white 10%)}.tng-button--error{background-color:var(--tng-error);color:#fff}.tng-button--error:hover{background-color: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),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 });
34
37
  }
35
38
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngButton, decorators: [{
36
39
  type: Component,
@@ -44,7 +47,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
44
47
  '[class.tng-button--rounded]': 'rounded()',
45
48
  '[class.tng-button--soft]': 'soft()',
46
49
  '(click)': 'createRipple($event)',
47
- }, 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;-webkit-appearance:none;overflow:hidden;vertical-align:middle;background:transparent;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-color:var(--tng-primary);color:var(--tng-primary-contrast)}.tng-button--primary:hover{background-color:color-mix(in srgb,var(--tng-primary),white 10%)}.tng-button--secondary{background-color:var(--tng-secondary);color:var(--tng-secondary-contrast)}.tng-button--secondary:hover{background-color:color-mix(in srgb,var(--tng-secondary),white 10%)}.tng-button--success{background-color:var(--tng-success);color:#fff}.tng-button--success:hover{background-color:color-mix(in srgb,var(--tng-success),white 10%)}.tng-button--warning{background-color:var(--tng-warning);color:#fff}.tng-button--warning:hover{background-color:color-mix(in srgb,var(--tng-warning),white 10%)}.tng-button--error{background-color:var(--tng-error);color:#fff}.tng-button--error:hover{background-color: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),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"] }]
48
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 }] }] } });
49
52
 
50
53
  class TngCardComponent {
@@ -56,7 +59,7 @@ class TngCardComponent {
56
59
  image = input(null, ...(ngDevMode ? [{ debugName: "image" }] : []));
57
60
  imageAlt = input('Card image', ...(ngDevMode ? [{ debugName: "imageAlt" }] : []));
58
61
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
59
- 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-color: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-color: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-color: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-color: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-color: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:#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 });
60
63
  }
61
64
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngCardComponent, decorators: [{
62
65
  type: Component,
@@ -69,7 +72,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
69
72
  '[class.tng-card--error]': 'variant() === "error"',
70
73
  '[class.tng-card--elevated]': 'elevated()',
71
74
  '[class.tng-card--outlined]': 'outlined()',
72
- }, 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-color: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-color: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-color: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-color: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-color: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:#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"] }]
73
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 }] }] } });
74
77
 
75
78
  class TecnualInputComponent {
@@ -311,13 +314,13 @@ class TecnualDatepickerComponent {
311
314
  }
312
315
  }
313
316
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TecnualDatepickerComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
314
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.0", type: TecnualDatepickerComponent, isStandalone: true, selector: "tng-datepicker", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { disabled: "disabledChange" }, host: { listeners: { "document:click": "onClickOutside($event)" } }, providers: [
317
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.0", type: TecnualDatepickerComponent, isStandalone: true, selector: "tng-datepicker", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { disabled: "disabledChange" }, host: { listeners: { "document:click": "onClickOutside($event)" } }, providers: [
315
318
  {
316
319
  provide: NG_VALUE_ACCESSOR,
317
320
  useExisting: forwardRef(() => TecnualDatepickerComponent),
318
321
  multi: true
319
322
  }
320
- ], 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 <div class=\"tng-calendar-popup\" *ngIf=\"isOpen()\">\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 <div class=\"day-name\" *ngFor=\"let day of daysOfWeek\">{{ day }}</div>\n <div\n class=\"day-cell\"\n *ngFor=\"let date of calendarDays()\"\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 </div>\n </div>\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: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }] });
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 }] });
321
324
  }
322
325
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TecnualDatepickerComponent, decorators: [{
323
326
  type: Component,
@@ -327,7 +330,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
327
330
  useExisting: forwardRef(() => TecnualDatepickerComponent),
328
331
  multi: true
329
332
  }
330
- ], 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 <div class=\"tng-calendar-popup\" *ngIf=\"isOpen()\">\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 <div class=\"day-name\" *ngFor=\"let day of daysOfWeek\">{{ day }}</div>\n <div\n class=\"day-cell\"\n *ngFor=\"let date of calendarDays()\"\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 </div>\n </div>\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"] }]
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"] }]
331
334
  }], 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: [{
332
335
  type: HostListener,
333
336
  args: ['document:click', ['$event']]
@@ -407,11 +410,11 @@ class TecnualTableComponent {
407
410
  this.onSearch(input.value);
408
411
  }
409
412
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TecnualTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
410
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.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 <div class=\"tng-table-toolbar\" *ngIf=\"filterable()\">\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 <!-- Table -->\n <div class=\"tng-table-wrapper\">\n <table class=\"tng-table\">\n <thead>\n <tr>\n <th \n *ngFor=\"let col of columns()\"\n [style.width]=\"col.width\"\n [class.sortable]=\"col.sortable\"\n (click)=\"onSort(col)\"\n >\n <div class=\"th-content\">\n {{ col.label }}\n <span class=\"sort-indicator\" *ngIf=\"sortColumn() === col.key\">\n {{ sortDirection() === 'asc' ? '\u2191' : '\u2193' }}\n </span>\n </div>\n </th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of paginatedData()\">\n <td *ngFor=\"let col of columns()\">\n <ng-container *ngIf=\"col.template; else defaultCell\">\n <ng-container *ngTemplateOutlet=\"col.template; context: { $implicit: row[col.key], row: row }\"></ng-container>\n </ng-container>\n <ng-template #defaultCell>\n {{ row[col.key] }}\n </ng-template>\n </td>\n </tr>\n <tr *ngIf=\"paginatedData().length === 0\" class=\"no-data-row\">\n <td [attr.colspan]=\"columns().length\">\n No data found\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <!-- Pagination -->\n <div class=\"tng-table-pagination\" *ngIf=\"totalPages() > 1\">\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 <ng-container *ngFor=\"let page of [].constructor(totalPages()); let i = index\">\n <!-- Show limited pages logic could go here, for now simple list -->\n <button \n *ngIf=\"i + 1 === currentPage() || i + 1 === 1 || i + 1 === totalPages() || (i + 1 >= currentPage() - 1 && i + 1 <= currentPage() + 1)\"\n class=\"tng-btn-page\"\n [class.active]=\"currentPage() === i + 1\"\n (click)=\"setPage(i + 1)\"\n >\n {{ i + 1 }}\n </button>\n <span *ngIf=\"(i + 1 === 2 && currentPage() > 4) || (i + 1 === totalPages() - 1 && currentPage() < totalPages() - 3)\" class=\"pagination-dots\">...</span>\n </ng-container>\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</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.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { 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"] }] });
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"] }] });
411
414
  }
412
415
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TecnualTableComponent, decorators: [{
413
416
  type: Component,
414
- args: [{ selector: 'tng-table', standalone: true, imports: [CommonModule, FormsModule, TecnualInputComponent], template: "<div class=\"tng-table-container\">\n <!-- Toolbar -->\n <div class=\"tng-table-toolbar\" *ngIf=\"filterable()\">\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 <!-- Table -->\n <div class=\"tng-table-wrapper\">\n <table class=\"tng-table\">\n <thead>\n <tr>\n <th \n *ngFor=\"let col of columns()\"\n [style.width]=\"col.width\"\n [class.sortable]=\"col.sortable\"\n (click)=\"onSort(col)\"\n >\n <div class=\"th-content\">\n {{ col.label }}\n <span class=\"sort-indicator\" *ngIf=\"sortColumn() === col.key\">\n {{ sortDirection() === 'asc' ? '\u2191' : '\u2193' }}\n </span>\n </div>\n </th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of paginatedData()\">\n <td *ngFor=\"let col of columns()\">\n <ng-container *ngIf=\"col.template; else defaultCell\">\n <ng-container *ngTemplateOutlet=\"col.template; context: { $implicit: row[col.key], row: row }\"></ng-container>\n </ng-container>\n <ng-template #defaultCell>\n {{ row[col.key] }}\n </ng-template>\n </td>\n </tr>\n <tr *ngIf=\"paginatedData().length === 0\" class=\"no-data-row\">\n <td [attr.colspan]=\"columns().length\">\n No data found\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n\n <!-- Pagination -->\n <div class=\"tng-table-pagination\" *ngIf=\"totalPages() > 1\">\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 <ng-container *ngFor=\"let page of [].constructor(totalPages()); let i = index\">\n <!-- Show limited pages logic could go here, for now simple list -->\n <button \n *ngIf=\"i + 1 === currentPage() || i + 1 === 1 || i + 1 === totalPages() || (i + 1 >= currentPage() - 1 && i + 1 <= currentPage() + 1)\"\n class=\"tng-btn-page\"\n [class.active]=\"currentPage() === i + 1\"\n (click)=\"setPage(i + 1)\"\n >\n {{ i + 1 }}\n </button>\n <span *ngIf=\"(i + 1 === 2 && currentPage() > 4) || (i + 1 === totalPages() - 1 && currentPage() < totalPages() - 3)\" class=\"pagination-dots\">...</span>\n </ng-container>\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</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"] }]
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"] }]
415
418
  }], 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 }] }] } });
416
419
 
417
420
  class TngToolbarComponent {
@@ -420,7 +423,7 @@ class TngToolbarComponent {
420
423
  color = input('default', ...(ngDevMode ? [{ debugName: "color" }] : []));
421
424
  elevation = input(true, ...(ngDevMode ? [{ debugName: "elevation" }] : []));
422
425
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
423
- 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--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--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-color:var(--tng-primary);color:var(--tng-primary-contrast)}.tng-toolbar--secondary{background-color:var(--tng-secondary);color:var(--tng-secondary-contrast)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
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--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--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 });
424
427
  }
425
428
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngToolbarComponent, decorators: [{
426
429
  type: Component,
@@ -435,7 +438,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
435
438
  '[class.tng-toolbar--primary]': 'color() === "primary"',
436
439
  '[class.tng-toolbar--secondary]': 'color() === "secondary"',
437
440
  '[class.tng-toolbar--elevated]': 'elevation()',
438
- }, 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--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-color:var(--tng-primary);color:var(--tng-primary-contrast)}.tng-toolbar--secondary{background-color:var(--tng-secondary);color:var(--tng-secondary-contrast)}\n"] }]
441
+ }, 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--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"] }]
439
442
  }], 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 }] }] } });
440
443
 
441
444
  class ThemeService {
@@ -490,6 +493,20 @@ class ThemeService {
490
493
  description: 'Elegant grayscale',
491
494
  primaryColor: '#616161',
492
495
  isDark: false
496
+ },
497
+ {
498
+ name: 'aurora',
499
+ displayName: 'Aurora',
500
+ description: 'Elegant gradients',
501
+ primaryColor: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
502
+ isDark: false
503
+ },
504
+ {
505
+ name: 'aurora-dark',
506
+ displayName: 'Aurora Dark',
507
+ description: 'Dark mode gradients',
508
+ primaryColor: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
509
+ isDark: true
493
510
  }
494
511
  ];
495
512
  constructor() {
@@ -509,17 +526,33 @@ class ThemeService {
509
526
  }
510
527
  applyTheme(theme) {
511
528
  console.log('Applying theme:', theme);
512
- // Remove all theme classes
529
+ // Remove all theme classes (optional if we rely solely on CSS files, but good for safety)
513
530
  this.themes.forEach(t => {
514
531
  document.body.classList.remove(`${t.name}-theme`);
515
532
  });
516
- // Add new theme class
533
+ // Add new theme class (still useful for component-level hooks)
517
534
  document.body.classList.add(`${theme}-theme`);
518
535
  // Set data attribute for CSS
519
536
  document.body.setAttribute('data-theme', theme);
537
+ // Load the theme CSS file
538
+ this.loadThemeCss(theme);
520
539
  console.log('Body classes:', document.body.className);
521
540
  console.log('Data theme:', document.body.getAttribute('data-theme'));
522
541
  }
542
+ loadThemeCss(theme) {
543
+ const head = document.head;
544
+ const existingLink = document.getElementById('theme-css');
545
+ const link = document.createElement('link');
546
+ link.id = 'theme-css';
547
+ link.rel = 'stylesheet';
548
+ link.href = `theme-${theme}.css`;
549
+ if (existingLink) {
550
+ head.replaceChild(link, existingLink);
551
+ }
552
+ else {
553
+ head.appendChild(link);
554
+ }
555
+ }
523
556
  loadTheme() {
524
557
  const saved = localStorage.getItem(this.STORAGE_KEY);
525
558
  return saved || 'light';
@@ -540,6 +573,446 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
540
573
  }]
541
574
  }], ctorParameters: () => [] });
542
575
 
576
+ class TngTooltipComponent {
577
+ content = input('', ...(ngDevMode ? [{ debugName: "content" }] : []));
578
+ isTemplate(value) {
579
+ return value instanceof TemplateRef;
580
+ }
581
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngTooltipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
582
+ 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: `
583
+ <div class="tng-tooltip-container" [@tooltipAnimation]>
584
+ @if (isTemplate(content())) {
585
+ <ng-container *ngTemplateOutlet="$any(content())"></ng-container>
586
+ } @else {
587
+ {{ content() }}
588
+ }
589
+ </div>
590
+ `, 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: [
591
+ trigger('tooltipAnimation', [
592
+ transition(':enter', [
593
+ style({ opacity: 0, transform: 'scale(0.9)' }),
594
+ animate('150ms cubic-bezier(0.25, 0.8, 0.25, 1)', style({ opacity: 1, transform: 'scale(1)' }))
595
+ ]),
596
+ transition(':leave', [
597
+ animate('100ms ease-out', style({ opacity: 0, transform: 'scale(0.9)' }))
598
+ ])
599
+ ])
600
+ ], changeDetection: i0.ChangeDetectionStrategy.OnPush });
601
+ }
602
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngTooltipComponent, decorators: [{
603
+ type: Component,
604
+ args: [{ selector: 'tng-tooltip', standalone: true, imports: [CommonModule], template: `
605
+ <div class="tng-tooltip-container" [@tooltipAnimation]>
606
+ @if (isTemplate(content())) {
607
+ <ng-container *ngTemplateOutlet="$any(content())"></ng-container>
608
+ } @else {
609
+ {{ content() }}
610
+ }
611
+ </div>
612
+ `, animations: [
613
+ trigger('tooltipAnimation', [
614
+ transition(':enter', [
615
+ style({ opacity: 0, transform: 'scale(0.9)' }),
616
+ animate('150ms cubic-bezier(0.25, 0.8, 0.25, 1)', style({ opacity: 1, transform: 'scale(1)' }))
617
+ ]),
618
+ transition(':leave', [
619
+ animate('100ms ease-out', style({ opacity: 0, transform: 'scale(0.9)' }))
620
+ ])
621
+ ])
622
+ ], 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"] }]
623
+ }], propDecorators: { content: [{ type: i0.Input, args: [{ isSignal: true, alias: "content", required: false }] }] } });
624
+
625
+ class TngTooltipDirective {
626
+ elementRef;
627
+ appRef;
628
+ injector;
629
+ content = '';
630
+ tngTooltipPosition = 'top';
631
+ tngTooltipDelay = 200;
632
+ componentRef = null;
633
+ timeoutId;
634
+ constructor(elementRef, appRef, injector) {
635
+ this.elementRef = elementRef;
636
+ this.appRef = appRef;
637
+ this.injector = injector;
638
+ }
639
+ onMouseEnter() {
640
+ this.timeoutId = setTimeout(() => {
641
+ this.show();
642
+ }, this.tngTooltipDelay);
643
+ }
644
+ onMouseLeave() {
645
+ if (this.timeoutId) {
646
+ clearTimeout(this.timeoutId);
647
+ }
648
+ this.hide();
649
+ }
650
+ onFocus() {
651
+ this.show();
652
+ }
653
+ onBlur() {
654
+ this.hide();
655
+ }
656
+ show() {
657
+ if (this.componentRef)
658
+ return;
659
+ // Create component
660
+ this.componentRef = createComponent(TngTooltipComponent, {
661
+ environmentInjector: this.injector
662
+ });
663
+ // Set input using setInput for signal-based inputs
664
+ this.componentRef.setInput('content', this.content);
665
+ // Trigger change detection to render content
666
+ this.componentRef.changeDetectorRef.detectChanges();
667
+ // Attach to the view so change detection works
668
+ this.appRef.attachView(this.componentRef.hostView);
669
+ // Get DOM element
670
+ const domElem = this.componentRef.hostView.rootNodes[0];
671
+ document.body.appendChild(domElem);
672
+ // Position it
673
+ this.updatePosition(domElem);
674
+ }
675
+ hide() {
676
+ if (!this.componentRef)
677
+ return;
678
+ this.appRef.detachView(this.componentRef.hostView);
679
+ this.componentRef.destroy();
680
+ this.componentRef = null;
681
+ }
682
+ updatePosition(tooltipElem) {
683
+ const hostRect = this.elementRef.nativeElement.getBoundingClientRect();
684
+ const tooltipRect = tooltipElem.getBoundingClientRect();
685
+ let top = 0;
686
+ let left = 0;
687
+ const gap = 8;
688
+ switch (this.tngTooltipPosition) {
689
+ case 'top':
690
+ top = hostRect.top - tooltipRect.height - gap;
691
+ left = hostRect.left + (hostRect.width - tooltipRect.width) / 2;
692
+ break;
693
+ case 'bottom':
694
+ top = hostRect.bottom + gap;
695
+ left = hostRect.left + (hostRect.width - tooltipRect.width) / 2;
696
+ break;
697
+ case 'left':
698
+ top = hostRect.top + (hostRect.height - tooltipRect.height) / 2;
699
+ left = hostRect.left - tooltipRect.width - gap;
700
+ break;
701
+ case 'right':
702
+ top = hostRect.top + (hostRect.height - tooltipRect.height) / 2;
703
+ left = hostRect.right + gap;
704
+ break;
705
+ }
706
+ // Prevent overflow (basic)
707
+ if (top < 0)
708
+ top = hostRect.bottom + gap; // Flip to bottom if top overflows
709
+ if (left < 0)
710
+ left = 0;
711
+ tooltipElem.style.top = `${top}px`;
712
+ tooltipElem.style.left = `${left}px`;
713
+ }
714
+ ngOnDestroy() {
715
+ this.hide();
716
+ }
717
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngTooltipDirective, deps: [{ token: i0.ElementRef }, { token: i0.ApplicationRef }, { token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Directive });
718
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.0", type: TngTooltipDirective, isStandalone: true, selector: "[tngTooltip]", inputs: { content: ["tngTooltip", "content"], tngTooltipPosition: "tngTooltipPosition", tngTooltipDelay: "tngTooltipDelay" }, host: { listeners: { "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()", "focus": "onFocus()", "blur": "onBlur()" } }, ngImport: i0 });
719
+ }
720
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngTooltipDirective, decorators: [{
721
+ type: Directive,
722
+ args: [{
723
+ selector: '[tngTooltip]',
724
+ standalone: true
725
+ }]
726
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ApplicationRef }, { type: i0.EnvironmentInjector }], propDecorators: { content: [{
727
+ type: Input,
728
+ args: ['tngTooltip']
729
+ }], tngTooltipPosition: [{
730
+ type: Input
731
+ }], tngTooltipDelay: [{
732
+ type: Input
733
+ }], onMouseEnter: [{
734
+ type: HostListener,
735
+ args: ['mouseenter']
736
+ }], onMouseLeave: [{
737
+ type: HostListener,
738
+ args: ['mouseleave']
739
+ }], onFocus: [{
740
+ type: HostListener,
741
+ args: ['focus']
742
+ }], onBlur: [{
743
+ type: HostListener,
744
+ args: ['blur']
745
+ }] } });
746
+
747
+ class TngExpansionPanelComponent {
748
+ // Signal inputs
749
+ title = input('Panel Title', ...(ngDevMode ? [{ debugName: "title" }] : []));
750
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
751
+ expanded = input(false, ...(ngDevMode ? [{ debugName: "expanded" }] : []));
752
+ // Signal output
753
+ toggled = output();
754
+ // Internal state
755
+ isExpanded = signal(false, ...(ngDevMode ? [{ debugName: "isExpanded" }] : []));
756
+ constructor() {
757
+ // Sync the expanded input with internal state
758
+ effect(() => {
759
+ this.isExpanded.set(this.expanded());
760
+ });
761
+ }
762
+ toggle() {
763
+ if (this.disabled())
764
+ return;
765
+ const newState = !this.isExpanded();
766
+ this.isExpanded.set(newState);
767
+ this.toggled.emit(newState);
768
+ }
769
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngExpansionPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
770
+ 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: [
771
+ trigger('expandCollapse', [
772
+ transition(':enter', [
773
+ style({ height: '0', opacity: '0', overflow: 'hidden' }),
774
+ animate('300ms cubic-bezier(0.4, 0.0, 0.2, 1)', style({ height: '*', opacity: '1' }))
775
+ ]),
776
+ transition(':leave', [
777
+ style({ height: '*', opacity: '1', overflow: 'hidden' }),
778
+ animate('300ms cubic-bezier(0.4, 0.0, 0.2, 1)', style({ height: '0', opacity: '0' }))
779
+ ])
780
+ ])
781
+ ], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
782
+ }
783
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngExpansionPanelComponent, decorators: [{
784
+ type: Component,
785
+ args: [{ selector: 'tng-expansion-panel', standalone: true, imports: [CommonModule], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, animations: [
786
+ trigger('expandCollapse', [
787
+ transition(':enter', [
788
+ style({ height: '0', opacity: '0', overflow: 'hidden' }),
789
+ animate('300ms cubic-bezier(0.4, 0.0, 0.2, 1)', style({ height: '*', opacity: '1' }))
790
+ ]),
791
+ transition(':leave', [
792
+ style({ height: '*', opacity: '1', overflow: 'hidden' }),
793
+ animate('300ms cubic-bezier(0.4, 0.0, 0.2, 1)', style({ height: '0', opacity: '0' }))
794
+ ])
795
+ ])
796
+ ], host: {
797
+ 'class': 'tng-expansion-panel',
798
+ '[class.tng-expansion-panel--expanded]': 'isExpanded()',
799
+ '[class.tng-expansion-panel--disabled]': 'disabled()'
800
+ }, 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"] }]
801
+ }], 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"] }] } });
802
+
803
+ class TngMenuComponent {
804
+ mode = input('vertical', ...(ngDevMode ? [{ debugName: "mode" }] : []));
805
+ density = input('comfortable', ...(ngDevMode ? [{ debugName: "density" }] : []));
806
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
807
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.0", type: TngMenuComponent, isStandalone: true, selector: "tng-menu", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, density: { classPropertyName: "density", publicName: "density", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
808
+ <nav class="tng-menu"
809
+ [class.tng-menu--horizontal]="mode() === 'horizontal'"
810
+ [class.tng-menu--vertical]="mode() === 'vertical'"
811
+ [class.tng-menu--compact]="density() === 'compact'"
812
+ [class.tng-menu--comfortable]="density() === 'comfortable'">
813
+ <ng-content></ng-content>
814
+ </nav>
815
+ `, 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 }] });
816
+ }
817
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngMenuComponent, decorators: [{
818
+ type: Component,
819
+ args: [{ selector: 'tng-menu', standalone: true, imports: [CommonModule], template: `
820
+ <nav class="tng-menu"
821
+ [class.tng-menu--horizontal]="mode() === 'horizontal'"
822
+ [class.tng-menu--vertical]="mode() === 'vertical'"
823
+ [class.tng-menu--compact]="density() === 'compact'"
824
+ [class.tng-menu--comfortable]="density() === 'comfortable'">
825
+ <ng-content></ng-content>
826
+ </nav>
827
+ `, 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"] }]
828
+ }], propDecorators: { mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], density: [{ type: i0.Input, args: [{ isSignal: true, alias: "density", required: false }] }] } });
829
+
830
+ class TngMenuItemComponent {
831
+ icon = input(...(ngDevMode ? [undefined, { debugName: "icon" }] : []));
832
+ label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
833
+ route = input(...(ngDevMode ? [undefined, { debugName: "route" }] : []));
834
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
835
+ level = input(0, ...(ngDevMode ? [{ debugName: "level" }] : []));
836
+ children;
837
+ expanded = signal(false, ...(ngDevMode ? [{ debugName: "expanded" }] : []));
838
+ hasChildren = signal(false, ...(ngDevMode ? [{ debugName: "hasChildren" }] : []));
839
+ ngAfterContentInit() {
840
+ // Check if there are any projected menu items
841
+ this.updateHasChildren();
842
+ // Listen for changes in children
843
+ this.children.changes.subscribe(() => {
844
+ this.updateHasChildren();
845
+ });
846
+ }
847
+ updateHasChildren() {
848
+ this.hasChildren.set(this.children.length > 0);
849
+ }
850
+ handleClick(event) {
851
+ if (this.disabled()) {
852
+ event.preventDefault();
853
+ return;
854
+ }
855
+ if (this.hasChildren()) {
856
+ event.preventDefault();
857
+ this.toggleExpanded();
858
+ }
859
+ }
860
+ toggleExpanded() {
861
+ this.expanded.update(value => !value);
862
+ }
863
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngMenuItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
864
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.0", type: TngMenuItemComponent, isStandalone: true, selector: "tng-menu-item", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, route: { classPropertyName: "route", publicName: "route", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, level: { classPropertyName: "level", publicName: "level", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "children", predicate: TngMenuItemComponent }], ngImport: i0, template: `
865
+ <div class="tng-menu-item"
866
+ [class.tng-menu-item--disabled]="disabled()"
867
+ [class.tng-menu-item--has-children]="hasChildren()"
868
+ [class.tng-menu-item--expanded]="expanded()"
869
+ [style.--level]="level()">
870
+
871
+ <!-- Item content (clickable) -->
872
+ @if (route() && !hasChildren()) {
873
+ <a [routerLink]="route()"
874
+ routerLinkActive="tng-menu-item__link--active"
875
+ class="tng-menu-item__link"
876
+ [class.tng-menu-item__link--disabled]="disabled()"
877
+ (click)="handleClick($event)">
878
+ @if (icon()) {
879
+ <span class="tng-menu-item__icon">
880
+ <span class="material-icons">{{ icon() }}</span>
881
+ </span>
882
+ }
883
+ <span class="tng-menu-item__label">
884
+ <ng-content select="[menu-item-label]"></ng-content>
885
+ {{ label() }}
886
+ </span>
887
+ @if (hasChildren()) {
888
+ <span class="tng-menu-item__chevron">
889
+ <span class="material-icons">expand_more</span>
890
+ </span>
891
+ }
892
+ </a>
893
+ } @else {
894
+ <button type="button"
895
+ class="tng-menu-item__link"
896
+ [class.tng-menu-item__link--disabled]="disabled()"
897
+ [disabled]="disabled()"
898
+ (click)="handleClick($event)">
899
+ @if (icon()) {
900
+ <span class="tng-menu-item__icon">
901
+ <span class="material-icons">{{ icon() }}</span>
902
+ </span>
903
+ }
904
+ <span class="tng-menu-item__label">
905
+ <ng-content select="[menu-item-label]"></ng-content>
906
+ {{ label() }}
907
+ </span>
908
+ @if (hasChildren()) {
909
+ <span class="tng-menu-item__chevron">
910
+ <span class="material-icons">expand_more</span>
911
+ </span>
912
+ }
913
+ </button>
914
+ }
915
+
916
+ <!-- Submenu (content projection for nested items) -->
917
+ @if (hasChildren() && expanded()) {
918
+ <div class="tng-menu-item__submenu">
919
+ <ng-content></ng-content>
920
+ </div>
921
+ }
922
+ </div>
923
+ `, isInline: true, styles: [".tng-menu-item{display:block;position:relative}.tng-menu-item__link{display:flex;align-items:center;padding:12px 16px;padding-left:calc(16px + var(--level, 0) * 24px);text-decoration:none;color:var(--tng-text, #333);background:transparent;border:none;border-left:3px solid transparent;width:100%;text-align:left;cursor:pointer;transition:all .2s cubic-bezier(.4,0,.2,1);position:relative;overflow:hidden;font-family:inherit;font-size:14px}.tng-menu-item__link:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;border-radius:50%;background:#0000000d;transform:translate(-50%,-50%);transition:width .6s,height .6s}.tng-menu-item__link:hover:not(.tng-menu-item__link--disabled){background-color:color-mix(in srgb,var(--tng-primary, #3f51b5),white 95%)}.tng-menu-item__link:hover:not(.tng-menu-item__link--disabled):before{width:300px;height:300px}.tng-menu-item__link:active:not(.tng-menu-item__link--disabled){transform:scale(.98)}.tng-menu-item__link--active{background-color:color-mix(in srgb,var(--tng-primary, #3f51b5),white 90%);border-left-color:var(--tng-primary, #3f51b5);color:var(--tng-primary, #3f51b5);font-weight:500}.tng-menu-item__link--active .tng-menu-item__icon{color:var(--tng-primary, #3f51b5)}.tng-menu-item__link--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.tng-menu-item__icon{display:flex;align-items:center;justify-content:center;margin-right:16px;color:var(--tng-text-secondary, #666);transition:color .2s}.tng-menu-item__icon .material-icons{font-size:20px}.tng-menu-item__label{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tng-menu-item__chevron{display:flex;align-items:center;margin-left:8px;transition:transform .3s cubic-bezier(.4,0,.2,1)}.tng-menu-item__chevron .material-icons{font-size:20px;color:var(--tng-text-secondary, #666)}.tng-menu-item--expanded .tng-menu-item__chevron{transform:rotate(180deg)}.tng-menu-item__submenu{overflow:hidden;animation:slideDown .3s cubic-bezier(.4,0,.2,1);background:color-mix(in srgb,var(--tng-surface, white),black 2%)}.tng-menu-item--has-children .tng-menu-item__link:hover .tng-menu-item__chevron .material-icons{color:var(--tng-primary, #3f51b5)}@keyframes slideDown{0%{max-height:0;opacity:0}to{max-height:500px;opacity:1}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i1$1.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }] });
924
+ }
925
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngMenuItemComponent, decorators: [{
926
+ type: Component,
927
+ args: [{ selector: 'tng-menu-item', standalone: true, imports: [CommonModule, RouterModule], template: `
928
+ <div class="tng-menu-item"
929
+ [class.tng-menu-item--disabled]="disabled()"
930
+ [class.tng-menu-item--has-children]="hasChildren()"
931
+ [class.tng-menu-item--expanded]="expanded()"
932
+ [style.--level]="level()">
933
+
934
+ <!-- Item content (clickable) -->
935
+ @if (route() && !hasChildren()) {
936
+ <a [routerLink]="route()"
937
+ routerLinkActive="tng-menu-item__link--active"
938
+ class="tng-menu-item__link"
939
+ [class.tng-menu-item__link--disabled]="disabled()"
940
+ (click)="handleClick($event)">
941
+ @if (icon()) {
942
+ <span class="tng-menu-item__icon">
943
+ <span class="material-icons">{{ icon() }}</span>
944
+ </span>
945
+ }
946
+ <span class="tng-menu-item__label">
947
+ <ng-content select="[menu-item-label]"></ng-content>
948
+ {{ label() }}
949
+ </span>
950
+ @if (hasChildren()) {
951
+ <span class="tng-menu-item__chevron">
952
+ <span class="material-icons">expand_more</span>
953
+ </span>
954
+ }
955
+ </a>
956
+ } @else {
957
+ <button type="button"
958
+ class="tng-menu-item__link"
959
+ [class.tng-menu-item__link--disabled]="disabled()"
960
+ [disabled]="disabled()"
961
+ (click)="handleClick($event)">
962
+ @if (icon()) {
963
+ <span class="tng-menu-item__icon">
964
+ <span class="material-icons">{{ icon() }}</span>
965
+ </span>
966
+ }
967
+ <span class="tng-menu-item__label">
968
+ <ng-content select="[menu-item-label]"></ng-content>
969
+ {{ label() }}
970
+ </span>
971
+ @if (hasChildren()) {
972
+ <span class="tng-menu-item__chevron">
973
+ <span class="material-icons">expand_more</span>
974
+ </span>
975
+ }
976
+ </button>
977
+ }
978
+
979
+ <!-- Submenu (content projection for nested items) -->
980
+ @if (hasChildren() && expanded()) {
981
+ <div class="tng-menu-item__submenu">
982
+ <ng-content></ng-content>
983
+ </div>
984
+ }
985
+ </div>
986
+ `, styles: [".tng-menu-item{display:block;position:relative}.tng-menu-item__link{display:flex;align-items:center;padding:12px 16px;padding-left:calc(16px + var(--level, 0) * 24px);text-decoration:none;color:var(--tng-text, #333);background:transparent;border:none;border-left:3px solid transparent;width:100%;text-align:left;cursor:pointer;transition:all .2s cubic-bezier(.4,0,.2,1);position:relative;overflow:hidden;font-family:inherit;font-size:14px}.tng-menu-item__link:before{content:\"\";position:absolute;top:50%;left:50%;width:0;height:0;border-radius:50%;background:#0000000d;transform:translate(-50%,-50%);transition:width .6s,height .6s}.tng-menu-item__link:hover:not(.tng-menu-item__link--disabled){background-color:color-mix(in srgb,var(--tng-primary, #3f51b5),white 95%)}.tng-menu-item__link:hover:not(.tng-menu-item__link--disabled):before{width:300px;height:300px}.tng-menu-item__link:active:not(.tng-menu-item__link--disabled){transform:scale(.98)}.tng-menu-item__link--active{background-color:color-mix(in srgb,var(--tng-primary, #3f51b5),white 90%);border-left-color:var(--tng-primary, #3f51b5);color:var(--tng-primary, #3f51b5);font-weight:500}.tng-menu-item__link--active .tng-menu-item__icon{color:var(--tng-primary, #3f51b5)}.tng-menu-item__link--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.tng-menu-item__icon{display:flex;align-items:center;justify-content:center;margin-right:16px;color:var(--tng-text-secondary, #666);transition:color .2s}.tng-menu-item__icon .material-icons{font-size:20px}.tng-menu-item__label{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.tng-menu-item__chevron{display:flex;align-items:center;margin-left:8px;transition:transform .3s cubic-bezier(.4,0,.2,1)}.tng-menu-item__chevron .material-icons{font-size:20px;color:var(--tng-text-secondary, #666)}.tng-menu-item--expanded .tng-menu-item__chevron{transform:rotate(180deg)}.tng-menu-item__submenu{overflow:hidden;animation:slideDown .3s cubic-bezier(.4,0,.2,1);background:color-mix(in srgb,var(--tng-surface, white),black 2%)}.tng-menu-item--has-children .tng-menu-item__link:hover .tng-menu-item__chevron .material-icons{color:var(--tng-primary, #3f51b5)}@keyframes slideDown{0%{max-height:0;opacity:0}to{max-height:500px;opacity:1}}\n"] }]
987
+ }], propDecorators: { icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], route: [{ type: i0.Input, args: [{ isSignal: true, alias: "route", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], level: [{ type: i0.Input, args: [{ isSignal: true, alias: "level", required: false }] }], children: [{
988
+ type: ContentChildren,
989
+ args: [TngMenuItemComponent]
990
+ }] } });
991
+
992
+ class TngMenuGroupComponent {
993
+ label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
994
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngMenuGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
995
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.0", type: TngMenuGroupComponent, isStandalone: true, selector: "tng-menu-group", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
996
+ <div class="tng-menu-group">
997
+ @if (label()) {
998
+ <div class="tng-menu-group__header">{{ label() }}</div>
999
+ }
1000
+ <ng-content></ng-content>
1001
+ </div>
1002
+ `, isInline: true, styles: [".tng-menu-group{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
1003
+ }
1004
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngMenuGroupComponent, decorators: [{
1005
+ type: Component,
1006
+ args: [{ selector: 'tng-menu-group', standalone: true, imports: [CommonModule], template: `
1007
+ <div class="tng-menu-group">
1008
+ @if (label()) {
1009
+ <div class="tng-menu-group__header">{{ label() }}</div>
1010
+ }
1011
+ <ng-content></ng-content>
1012
+ </div>
1013
+ `, styles: [".tng-menu-group{display:block}\n"] }]
1014
+ }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }] } });
1015
+
543
1016
  /*
544
1017
  * Public API Surface of tecnualng
545
1018
  */
@@ -548,5 +1021,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
548
1021
  * Generated bundle index. Do not edit.
549
1022
  */
550
1023
 
551
- export { TecnualDatepickerComponent, TecnualInputComponent, TecnualTableComponent, ThemeService, TngButton, TngCardComponent, TngToolbarComponent };
1024
+ export { TecnualDatepickerComponent, TecnualInputComponent, TecnualTableComponent, ThemeService, TngButton, TngCardComponent, TngExpansionPanelComponent, TngMenuComponent, TngMenuGroupComponent, TngMenuItemComponent, TngToolbarComponent, TngTooltipComponent, TngTooltipDirective };
552
1025
  //# sourceMappingURL=tecnualng.mjs.map