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