tecnualng 21.0.23 → 21.0.26

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.
@@ -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-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 });
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--basic": "variant() === \"basic\"", "class.tng-button--outlined": "variant() === \"outlined\"", "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%)}.tng-button--basic{background:transparent;color:var(--tng-text);border:none}.tng-button--basic:hover{background:color-mix(in srgb,var(--tng-text),transparent 95%);border:1px solid var(--tng-secondary)}.tng-button--outlined{background:transparent;color:var(--tng-text);border:1px solid color-mix(in srgb,var(--tng-primary),transparent 55%)}.tng-button--outlined:hover{background:color-mix(in srgb,var(--tng-text),transparent 95%);border-color:color-mix(in srgb,var(--tng-secondary),transparent 15%)}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,
@@ -44,10 +44,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
44
44
  '[class.tng-button--success]': 'variant() === "success"',
45
45
  '[class.tng-button--warning]': 'variant() === "warning"',
46
46
  '[class.tng-button--error]': 'variant() === "error"',
47
+ '[class.tng-button--basic]': 'variant() === "basic"',
48
+ '[class.tng-button--outlined]': 'variant() === "outlined"',
47
49
  '[class.tng-button--rounded]': 'rounded()',
48
50
  '[class.tng-button--soft]': 'soft()',
49
51
  '(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-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"] }]
52
+ }, 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%)}.tng-button--basic{background:transparent;color:var(--tng-text);border:none}.tng-button--basic:hover{background:color-mix(in srgb,var(--tng-text),transparent 95%);border:1px solid var(--tng-secondary)}.tng-button--outlined{background:transparent;color:var(--tng-text);border:1px solid color-mix(in srgb,var(--tng-primary),transparent 55%)}.tng-button--outlined:hover{background:color-mix(in srgb,var(--tng-text),transparent 95%);border-color:color-mix(in srgb,var(--tng-secondary),transparent 15%)}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
53
  }], 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
54
 
53
55
  class TngCardComponent {
@@ -230,21 +232,146 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
230
232
  args: ['change']
231
233
  }] } });
232
234
 
235
+ class TngTextareaDirective {
236
+ el = inject((ElementRef));
237
+ ngControl = inject(NgControl, { optional: true, self: true });
238
+ // Inputs
239
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
240
+ placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
241
+ maxLength = input(undefined, ...(ngDevMode ? [{ debugName: "maxLength" }] : []));
242
+ // State signals
243
+ focused = signal(false, ...(ngDevMode ? [{ debugName: "focused" }] : []));
244
+ _value = signal('', ...(ngDevMode ? [{ debugName: "_value" }] : []));
245
+ // Computed
246
+ hasValue = computed(() => {
247
+ const val = this._value();
248
+ return val !== null && val !== undefined && val !== '';
249
+ }, ...(ngDevMode ? [{ debugName: "hasValue" }] : []));
250
+ valueLength = computed(() => this._value().length, ...(ngDevMode ? [{ debugName: "valueLength" }] : []));
251
+ computedPlaceholder = computed(() => {
252
+ return this.focused() ? this.placeholder() : '';
253
+ }, ...(ngDevMode ? [{ debugName: "computedPlaceholder" }] : []));
254
+ constructor() {
255
+ effect(() => {
256
+ this.updateValue();
257
+ }, { allowSignalWrites: true });
258
+ }
259
+ onFocus() {
260
+ this.focused.set(true);
261
+ }
262
+ onBlur() {
263
+ this.focused.set(false);
264
+ this.updateValue();
265
+ }
266
+ onInput() {
267
+ this.updateValue();
268
+ }
269
+ ngAfterViewInit() {
270
+ this.updateValue();
271
+ }
272
+ updateValue() {
273
+ this._value.set(this.el.nativeElement.value);
274
+ }
275
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngTextareaDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
276
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.0", type: TngTextareaDirective, isStandalone: true, selector: "textarea[tngTextarea]", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, maxLength: { classPropertyName: "maxLength", publicName: "maxLength", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "focus": "onFocus()", "blur": "onBlur()", "input": "onInput()" }, properties: { "class.tng-textarea-field": "true", "disabled": "disabled()", "attr.maxlength": "maxLength() || null", "attr.placeholder": "computedPlaceholder()" } }, exportAs: ["tngTextarea"], ngImport: i0 });
277
+ }
278
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngTextareaDirective, decorators: [{
279
+ type: Directive,
280
+ args: [{
281
+ selector: 'textarea[tngTextarea]',
282
+ standalone: true,
283
+ host: {
284
+ '[class.tng-textarea-field]': 'true',
285
+ '[disabled]': 'disabled()',
286
+ '[attr.maxlength]': 'maxLength() || null',
287
+ '[attr.placeholder]': 'computedPlaceholder()'
288
+ },
289
+ exportAs: 'tngTextarea'
290
+ }]
291
+ }], ctorParameters: () => [], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], maxLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxLength", required: false }] }], onFocus: [{
292
+ type: HostListener,
293
+ args: ['focus']
294
+ }], onBlur: [{
295
+ type: HostListener,
296
+ args: ['blur']
297
+ }], onInput: [{
298
+ type: HostListener,
299
+ args: ['input']
300
+ }] } });
301
+
233
302
  class TngFormFieldComponent {
234
303
  label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
235
- // Query for the input directive inside this component
304
+ // Query for the input or textarea directive inside this component
236
305
  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" }] : []));
306
+ textareaDirective = contentChild(TngTextareaDirective, ...(ngDevMode ? [{ debugName: "textareaDirective" }] : []));
307
+ // Computed states based on the input/textarea directive
308
+ activeDirective = computed(() => this.inputDirective() || this.textareaDirective(), ...(ngDevMode ? [{ debugName: "activeDirective" }] : []));
309
+ isFocused = computed(() => this.activeDirective()?.focused() ?? false, ...(ngDevMode ? [{ debugName: "isFocused" }] : []));
310
+ hasValue = computed(() => this.activeDirective()?.hasValue() ?? false, ...(ngDevMode ? [{ debugName: "hasValue" }] : []));
311
+ isDisabled = computed(() => this.activeDirective()?.disabled() ?? false, ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
312
+ // Character count logic
313
+ maxLength = computed(() => this.textareaDirective()?.maxLength(), ...(ngDevMode ? [{ debugName: "maxLength" }] : []));
314
+ currentLength = computed(() => this.textareaDirective()?.valueLength() ?? 0, ...(ngDevMode ? [{ debugName: "currentLength" }] : []));
315
+ showCounter = computed(() => this.maxLength() !== undefined, ...(ngDevMode ? [{ debugName: "showCounter" }] : []));
316
+ // Style helper
317
+ hasTextarea = computed(() => !!this.textareaDirective(), ...(ngDevMode ? [{ debugName: "hasTextarea" }] : []));
241
318
  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 });
319
+ 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 }, { propertyName: "textareaDirective", first: true, predicate: TngTextareaDirective, 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 [class.tng-form-field-type-textarea]=\"hasTextarea()\">\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<div class=\"tng-form-field-subscript-wrapper\" *ngIf=\"showCounter()\">\n <div class=\"tng-form-field-spacer\"></div>\n <div class=\"tng-form-field-hint\">\n {{ currentLength() }} / {{ maxLength() }}\n </div>\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;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-input-container.tng-form-field-type-textarea{align-items:flex-start;height:auto}.tng-input-container.tng-form-field-type-textarea .tng-label{top:24px}.tng-input-container.tng-form-field-type-textarea.focused .tng-label,.tng-input-container.tng-form-field-type-textarea.has-value .tng-label{transform:translateY(-24px) scale(.75)}.tng-fieldset{position:absolute;inset:0;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;width:calc(100% - 32px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}input.tng-input-field,textarea.tng-input-field,textarea.tng-textarea-field{display:block;width:100%;border:none;background:none;padding:0 16px;margin:0;font-size:16px;color:var(--tng-text, #333);outline:none;min-height:48px;line-height:normal;z-index:1;font-family:inherit;box-sizing:border-box}input.tng-input-field::placeholder,textarea.tng-input-field::placeholder,textarea.tng-textarea-field::placeholder{color:transparent;transition:color .2s ease}input.tng-input-field:focus::placeholder,textarea.tng-input-field:focus::placeholder,textarea.tng-textarea-field:focus::placeholder{color:#aaa}textarea.tng-textarea-field{padding-top:12px;padding-bottom:12px;resize:vertical;height:auto;line-height:1.5}.tng-form-field-subscript-wrapper{margin-top:4px;font-size:.75rem;display:flex;justify-content:space-between;padding:0 16px}.tng-form-field-spacer{flex:1 1 auto}.tng-form-field-hint{color:var(--tng-text-secondary, #666);text-align:right}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], encapsulation: i0.ViewEncapsulation.None });
243
320
  }
244
321
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngFormFieldComponent, decorators: [{
245
322
  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 }] }] } });
323
+ 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 [class.tng-form-field-type-textarea]=\"hasTextarea()\">\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<div class=\"tng-form-field-subscript-wrapper\" *ngIf=\"showCounter()\">\n <div class=\"tng-form-field-spacer\"></div>\n <div class=\"tng-form-field-hint\">\n {{ currentLength() }} / {{ maxLength() }}\n </div>\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;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-input-container.tng-form-field-type-textarea{align-items:flex-start;height:auto}.tng-input-container.tng-form-field-type-textarea .tng-label{top:24px}.tng-input-container.tng-form-field-type-textarea.focused .tng-label,.tng-input-container.tng-form-field-type-textarea.has-value .tng-label{transform:translateY(-24px) scale(.75)}.tng-fieldset{position:absolute;inset:0;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;width:calc(100% - 32px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}input.tng-input-field,textarea.tng-input-field,textarea.tng-textarea-field{display:block;width:100%;border:none;background:none;padding:0 16px;margin:0;font-size:16px;color:var(--tng-text, #333);outline:none;min-height:48px;line-height:normal;z-index:1;font-family:inherit;box-sizing:border-box}input.tng-input-field::placeholder,textarea.tng-input-field::placeholder,textarea.tng-textarea-field::placeholder{color:transparent;transition:color .2s ease}input.tng-input-field:focus::placeholder,textarea.tng-input-field:focus::placeholder,textarea.tng-textarea-field:focus::placeholder{color:#aaa}textarea.tng-textarea-field{padding-top:12px;padding-bottom:12px;resize:vertical;height:auto;line-height:1.5}.tng-form-field-subscript-wrapper{margin-top:4px;font-size:.75rem;display:flex;justify-content:space-between;padding:0 16px}.tng-form-field-spacer{flex:1 1 auto}.tng-form-field-hint{color:var(--tng-text-secondary, #666);text-align:right}\n"] }]
324
+ }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], inputDirective: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TngInputDirective), { isSignal: true }] }], textareaDirective: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TngTextareaDirective), { isSignal: true }] }] } });
325
+
326
+ class TngTextareaComponent {
327
+ label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
328
+ placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
329
+ required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : []));
330
+ disabled = model(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
331
+ maxLength = input(undefined, ...(ngDevMode ? [{ debugName: "maxLength" }] : []));
332
+ id = input(`tng-textarea-${Math.random().toString(36).substr(2, 9)}`, ...(ngDevMode ? [{ debugName: "id" }] : []));
333
+ value = signal('', ...(ngDevMode ? [{ debugName: "value" }] : []));
334
+ onChange = () => { };
335
+ onTouched = () => { };
336
+ onInput(event) {
337
+ const input = event.target;
338
+ this.value.set(input.value);
339
+ this.onChange(this.value());
340
+ }
341
+ onBlur() {
342
+ this.onTouched();
343
+ }
344
+ writeValue(value) {
345
+ this.value.set(value || '');
346
+ }
347
+ registerOnChange(fn) {
348
+ this.onChange = fn;
349
+ }
350
+ registerOnTouched(fn) {
351
+ this.onTouched = fn;
352
+ }
353
+ setDisabledState(isDisabled) {
354
+ this.disabled.update(() => isDisabled);
355
+ }
356
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngTextareaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
357
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.0", type: TngTextareaComponent, isStandalone: true, selector: "tng-textarea", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, maxLength: { classPropertyName: "maxLength", publicName: "maxLength", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { disabled: "disabledChange" }, providers: [
358
+ {
359
+ provide: NG_VALUE_ACCESSOR,
360
+ useExisting: forwardRef(() => TngTextareaComponent),
361
+ multi: true
362
+ }
363
+ ], ngImport: i0, template: "<tng-form-field [label]=\"label()\">\n <textarea\n tngTextarea\n [id]=\"id()\"\n [placeholder]=\"placeholder()\"\n [value]=\"value()\"\n [disabled]=\"disabled()\"\n [maxLength]=\"maxLength()\"\n [required]=\"required()\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur()\">\n </textarea>\n</tng-form-field>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: TngFormFieldComponent, selector: "tng-form-field", inputs: ["label"] }, { kind: "directive", type: TngTextareaDirective, selector: "textarea[tngTextarea]", inputs: ["disabled", "placeholder", "maxLength"], exportAs: ["tngTextarea"] }], encapsulation: i0.ViewEncapsulation.None });
364
+ }
365
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngTextareaComponent, decorators: [{
366
+ type: Component,
367
+ args: [{ selector: 'tng-textarea', standalone: true, imports: [CommonModule, FormsModule, TngFormFieldComponent, TngTextareaDirective], providers: [
368
+ {
369
+ provide: NG_VALUE_ACCESSOR,
370
+ useExisting: forwardRef(() => TngTextareaComponent),
371
+ multi: true
372
+ }
373
+ ], encapsulation: ViewEncapsulation.None, template: "<tng-form-field [label]=\"label()\">\n <textarea\n tngTextarea\n [id]=\"id()\"\n [placeholder]=\"placeholder()\"\n [value]=\"value()\"\n [disabled]=\"disabled()\"\n [maxLength]=\"maxLength()\"\n [required]=\"required()\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur()\">\n </textarea>\n</tng-form-field>\n", styles: [":host{display:block}\n"] }]
374
+ }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", 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"] }], maxLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxLength", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }] } });
248
375
 
249
376
  class TecnualDatepickerComponent {
250
377
  elementRef;
@@ -1488,6 +1615,9 @@ class TngSelectDirective {
1488
1615
  panelRef = null;
1489
1616
  // Generated trigger element
1490
1617
  triggerEl = null;
1618
+ // Disabled state tracking
1619
+ isDisabled = signal(false, ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
1620
+ mutationObserver = null;
1491
1621
  // Computed
1492
1622
  isMulti = computed(() => this.enableMulti() || this.multiple(), ...(ngDevMode ? [{ debugName: "isMulti" }] : []));
1493
1623
  options = computed(() => this._options(), ...(ngDevMode ? [{ debugName: "options" }] : []));
@@ -1525,13 +1655,27 @@ class TngSelectDirective {
1525
1655
  this.ngControl.control.setValue(newValue, { emitEvent: false });
1526
1656
  }
1527
1657
  });
1528
- // Update generated trigger text
1658
+ // Update generated trigger text and state
1529
1659
  effect(() => {
1530
1660
  if (this.triggerEl) {
1531
- const textSpan = this.triggerEl.querySelector('.tng-select-trigger-text');
1661
+ const textSpan = this.triggerEl.querySelector('.tng-select-display-text');
1532
1662
  if (textSpan) {
1533
1663
  textSpan.textContent = this.displayText();
1534
1664
  }
1665
+ // Toggle open class
1666
+ if (this.isOpen()) {
1667
+ this.triggerEl.classList.add('tng-select-open');
1668
+ }
1669
+ else {
1670
+ this.triggerEl.classList.remove('tng-select-open');
1671
+ }
1672
+ // Toggle disabled class
1673
+ if (this.isDisabled()) {
1674
+ this.triggerEl.classList.add('disabled');
1675
+ }
1676
+ else {
1677
+ this.triggerEl.classList.remove('disabled');
1678
+ }
1535
1679
  }
1536
1680
  });
1537
1681
  }
@@ -1544,6 +1688,16 @@ class TngSelectDirective {
1544
1688
  this.el.nativeElement.style.pointerEvents = 'none';
1545
1689
  this.el.nativeElement.style.height = '0';
1546
1690
  this.el.nativeElement.style.width = '0';
1691
+ // Track disabled state
1692
+ this.isDisabled.set(this.el.nativeElement.disabled);
1693
+ this.mutationObserver = new MutationObserver((mutations) => {
1694
+ mutations.forEach((mutation) => {
1695
+ if (mutation.attributeName === 'disabled') {
1696
+ this.isDisabled.set(this.el.nativeElement.disabled);
1697
+ }
1698
+ });
1699
+ });
1700
+ this.mutationObserver.observe(this.el.nativeElement, { attributes: true });
1547
1701
  if (!this.customTrigger()) {
1548
1702
  this.createTrigger();
1549
1703
  }
@@ -1552,7 +1706,9 @@ class TngSelectDirective {
1552
1706
  this.closePanel();
1553
1707
  if (this.triggerEl) {
1554
1708
  this.triggerEl.remove();
1709
+ this.triggerEl = null;
1555
1710
  }
1711
+ this.mutationObserver?.disconnect();
1556
1712
  }
1557
1713
  onClick(event) {
1558
1714
  // If we have a generated trigger, the click is handled there.
@@ -1573,30 +1729,17 @@ class TngSelectDirective {
1573
1729
  }
1574
1730
  createTrigger() {
1575
1731
  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';
1732
+ trigger.className = 'tng-select-display';
1587
1733
  const text = document.createElement('span');
1588
- text.className = 'tng-select-trigger-text';
1734
+ text.className = 'tng-select-display-text';
1589
1735
  text.textContent = this.displayText();
1590
- text.style.flex = '1';
1591
- text.style.overflow = 'hidden';
1592
- text.style.textOverflow = 'ellipsis';
1593
- text.style.whiteSpace = 'nowrap';
1594
- const arrow = document.createElement('span');
1595
- arrow.innerHTML = '&#9662;'; // Down arrow
1596
- arrow.style.marginLeft = '0.5rem';
1736
+ const arrow = document.createElement('i');
1737
+ arrow.className = 'fa fa-chevron-down tng-select-arrow';
1597
1738
  trigger.appendChild(text);
1598
1739
  trigger.appendChild(arrow);
1599
1740
  trigger.addEventListener('click', (e) => {
1741
+ if (this.isDisabled())
1742
+ return;
1600
1743
  e.preventDefault();
1601
1744
  e.stopPropagation();
1602
1745
  this.togglePanel();
@@ -1879,7 +2022,7 @@ class TngSelectComponent {
1879
2022
  useExisting: forwardRef(() => TngSelectComponent),
1880
2023
  multi: true
1881
2024
  }
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 });
2025
+ ], 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;font-family:var(--tng-font-family, \"Inter\", sans-serif)}.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,.tng-select-display.tng-select-open{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,.tng-select-display.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, encapsulation: i0.ViewEncapsulation.None });
1883
2026
  }
1884
2027
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngSelectComponent, decorators: [{
1885
2028
  type: Component,
@@ -1889,7 +2032,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
1889
2032
  useExisting: forwardRef(() => TngSelectComponent),
1890
2033
  multi: true
1891
2034
  }
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"] }]
2035
+ ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, 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;font-family:var(--tng-font-family, \"Inter\", sans-serif)}.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,.tng-select-display.tng-select-open{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,.tng-select-display.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
2036
  }], 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
2037
 
1895
2038
  /*
@@ -1900,5 +2043,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
1900
2043
  * Generated bundle index. Do not edit.
1901
2044
  */
1902
2045
 
1903
- export { TecnualDatepickerComponent, TecnualInputComponent, TecnualTableComponent, ThemeService, TngButton, TngCardComponent, TngExpansionPanelComponent, TngFormFieldComponent, TngInputDirective, TngMenuComponent, TngMenuGroupComponent, TngMenuItemComponent, TngSelectComponent, TngSelectDirective, TngSelectPanelComponent, TngSidebarComponent, TngTabComponent, TngTabsComponent, TngToolbarComponent, TngTooltipComponent, TngTooltipDirective };
2046
+ export { TecnualDatepickerComponent, TecnualInputComponent, TecnualTableComponent, ThemeService, TngButton, TngCardComponent, TngExpansionPanelComponent, TngFormFieldComponent, TngInputDirective, TngMenuComponent, TngMenuGroupComponent, TngMenuItemComponent, TngSelectComponent, TngSelectDirective, TngSelectPanelComponent, TngSidebarComponent, TngTabComponent, TngTabsComponent, TngTextareaComponent, TngTextareaDirective, TngToolbarComponent, TngTooltipComponent, TngTooltipDirective };
1904
2047
  //# sourceMappingURL=tecnualng.mjs.map