tecnualng 21.1.8 → 21.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,10 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, ChangeDetectionStrategy, ViewEncapsulation, Component, inject, model, signal, computed, ElementRef, effect, HostListener, Directive, contentChild, forwardRef, viewChild, TemplateRef, contentChildren, Injectable, createComponent, Input, output, ContentChildren, ViewContainerRef, booleanAttribute } from '@angular/core';
2
+ import { input, ChangeDetectionStrategy, ViewEncapsulation, Component, inject, model, signal, computed, ElementRef, DestroyRef, effect, HostListener, Directive, contentChild, forwardRef, viewChild, TemplateRef, contentChildren, Injectable, createComponent, Input, output, ContentChildren, ViewContainerRef, booleanAttribute, untracked } from '@angular/core';
3
3
  import * as i1$2 from '@angular/forms';
4
4
  import { NgControl, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
5
5
  import * as i1 from '@angular/common';
6
6
  import { CommonModule } from '@angular/common';
7
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
7
8
  import * as i1$1 from '@angular/router';
8
9
  import { RouterModule } from '@angular/router';
9
10
 
@@ -133,6 +134,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
133
134
  class TngInputDirective {
134
135
  el = inject((ElementRef));
135
136
  ngControl = inject(NgControl, { optional: true, self: true });
137
+ destroyRef = inject(DestroyRef);
136
138
  // Inputs
137
139
  disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
138
140
  placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
@@ -162,6 +164,13 @@ class TngInputDirective {
162
164
  this.detectInputType();
163
165
  });
164
166
  }
167
+ ngOnInit() {
168
+ if (this.ngControl) {
169
+ this.ngControl.valueChanges?.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((val) => {
170
+ this._value.set(val);
171
+ });
172
+ }
173
+ }
165
174
  onFocus() {
166
175
  this.focused.set(true);
167
176
  }
@@ -194,7 +203,8 @@ class TngInputDirective {
194
203
  }
195
204
  }
196
205
  updateValue() {
197
- this._value.set(this.el.nativeElement.value);
206
+ const val = this.el.nativeElement.value;
207
+ this._value.set(val);
198
208
  }
199
209
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngInputDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
200
210
  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 });
@@ -229,6 +239,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
229
239
  class TngTextareaDirective {
230
240
  el = inject((ElementRef));
231
241
  ngControl = inject(NgControl, { optional: true, self: true });
242
+ destroyRef = inject(DestroyRef);
232
243
  // Inputs
233
244
  disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
234
245
  placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
@@ -250,6 +261,13 @@ class TngTextareaDirective {
250
261
  this.updateValue();
251
262
  });
252
263
  }
264
+ ngOnInit() {
265
+ if (this.ngControl) {
266
+ this.ngControl.valueChanges?.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((val) => {
267
+ this._value.set(val);
268
+ });
269
+ }
270
+ }
253
271
  onFocus() {
254
272
  this.focused.set(true);
255
273
  }
@@ -318,6 +336,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
318
336
  }], 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 }] }] } });
319
337
 
320
338
  class TngTextareaComponent {
339
+ ngControl = inject(NgControl, { optional: true, self: true });
321
340
  label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
322
341
  placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
323
342
  required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : []));
@@ -327,6 +346,11 @@ class TngTextareaComponent {
327
346
  value = signal('', ...(ngDevMode ? [{ debugName: "value" }] : []));
328
347
  onChange = () => { };
329
348
  onTouched = () => { };
349
+ constructor() {
350
+ if (this.ngControl) {
351
+ this.ngControl.valueAccessor = this;
352
+ }
353
+ }
330
354
  onInput(event) {
331
355
  const input = event.target;
332
356
  this.value.set(input.value);
@@ -345,27 +369,15 @@ class TngTextareaComponent {
345
369
  this.onTouched = fn;
346
370
  }
347
371
  setDisabledState(isDisabled) {
348
- this.disabled.update(() => isDisabled);
372
+ this.disabled.set(isDisabled);
349
373
  }
350
374
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngTextareaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
351
- 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: [
352
- {
353
- provide: NG_VALUE_ACCESSOR,
354
- useExisting: forwardRef(() => TngTextareaComponent),
355
- multi: true
356
- }
357
- ], 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 });
375
+ 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" }, 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 });
358
376
  }
359
377
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngTextareaComponent, decorators: [{
360
378
  type: Component,
361
- args: [{ selector: 'tng-textarea', standalone: true, imports: [CommonModule, FormsModule, TngFormFieldComponent, TngTextareaDirective], providers: [
362
- {
363
- provide: NG_VALUE_ACCESSOR,
364
- useExisting: forwardRef(() => TngTextareaComponent),
365
- multi: true
366
- }
367
- ], 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"] }]
368
- }], 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 }] }] } });
379
+ args: [{ selector: 'tng-textarea', standalone: true, imports: [CommonModule, FormsModule, TngFormFieldComponent, TngTextareaDirective], 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"] }]
380
+ }], ctorParameters: () => [], 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 }] }] } });
369
381
 
370
382
  class TecnualDatepickerComponent {
371
383
  elementRef;
@@ -1768,17 +1780,18 @@ class TngSelectPanelComponent {
1768
1780
  this.optionSelected.emit(index);
1769
1781
  }
1770
1782
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngSelectPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1771
- 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;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.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 });
1783
+ 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;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.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);background-color:var(--tng-surface, #ffffff);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 });
1772
1784
  }
1773
1785
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngSelectPanelComponent, decorators: [{
1774
1786
  type: Component,
1775
- 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;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.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"] }]
1787
+ 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;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.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);background-color:var(--tng-surface, #ffffff);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"] }]
1776
1788
  }], propDecorators: { optionSelected: [{ type: i0.Output, args: ["optionSelected"] }], searchQueryChanged: [{ type: i0.Output, args: ["searchQueryChanged"] }], closeRequested: [{ type: i0.Output, args: ["closeRequested"] }] } });
1777
1789
 
1778
1790
  class TngSelectDirective {
1779
1791
  el = inject((ElementRef));
1780
1792
  viewContainerRef = inject(ViewContainerRef);
1781
1793
  ngControl = inject(NgControl, { optional: true, self: true });
1794
+ destroyRef = inject(DestroyRef);
1782
1795
  // Inputs
1783
1796
  enableMulti = input(false, ...(ngDevMode ? [{ debugName: "enableMulti" }] : []));
1784
1797
  // Support native multiple attribute
@@ -1793,7 +1806,23 @@ class TngSelectDirective {
1793
1806
  isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
1794
1807
  searchQuery = signal('', ...(ngDevMode ? [{ debugName: "searchQuery" }] : []));
1795
1808
  _options = signal([], ...(ngDevMode ? [{ debugName: "_options" }] : []));
1796
- _selectedIndices = signal([], ...(ngDevMode ? [{ debugName: "_selectedIndices" }] : []));
1809
+ _selectedIndices = signal([], ...(ngDevMode ? [{ debugName: "_selectedIndices", equal: (a, b) => {
1810
+ if (a === b)
1811
+ return true;
1812
+ if (a.length !== b.length)
1813
+ return false;
1814
+ const sortedA = [...a].sort();
1815
+ const sortedB = [...b].sort();
1816
+ return sortedA.every((val, index) => val === sortedB[index]);
1817
+ } }] : [{ equal: (a, b) => {
1818
+ if (a === b)
1819
+ return true;
1820
+ if (a.length !== b.length)
1821
+ return false;
1822
+ const sortedA = [...a].sort();
1823
+ const sortedB = [...b].sort();
1824
+ return sortedA.every((val, index) => val === sortedB[index]);
1825
+ } }]));
1797
1826
  // Component reference for the panel
1798
1827
  panelRef = null;
1799
1828
  // Generated trigger element
@@ -1825,16 +1854,29 @@ class TngSelectDirective {
1825
1854
  return selected.map(opt => opt.label).join(', ');
1826
1855
  }, ...(ngDevMode ? [{ debugName: "displayText" }] : []));
1827
1856
  constructor() {
1828
- // Sync selected values with model
1857
+ // Sync selected values with model (Output)
1829
1858
  effect(() => {
1830
1859
  const selected = this.selectedOptions();
1860
+ // Use untracked to avoid loop if selectedValues write triggers immediate read dependency? No.
1831
1861
  this.selectedValues.set(selected.map(opt => opt.value));
1832
1862
  });
1863
+ // Sync model with internal (Input)
1864
+ effect(() => {
1865
+ const values = this.selectedValues();
1866
+ // Avoid infinite loop by checking if values actally represent a change
1867
+ const currentSelected = untracked(() => this.selectedOptions());
1868
+ const currentValues = currentSelected.map(o => o.value);
1869
+ // Simple equality check (value-based)
1870
+ if (values.length !== currentValues.length || !values.every((v, i) => v == currentValues[i])) { // weak eq
1871
+ this.updateSelectionFromValue(values);
1872
+ }
1873
+ });
1833
1874
  // Update form control value
1834
1875
  effect(() => {
1835
1876
  if (this.ngControl?.control) {
1836
1877
  const values = this.selectedValues();
1837
1878
  const newValue = this.isMulti() ? values : (values[0] ?? null);
1879
+ // Only setValue if changed? internal control handles checks usually
1838
1880
  this.ngControl.control.setValue(newValue, { emitEvent: false });
1839
1881
  }
1840
1882
  });
@@ -1862,6 +1904,33 @@ class TngSelectDirective {
1862
1904
  }
1863
1905
  });
1864
1906
  }
1907
+ ngOnInit() {
1908
+ if (this.ngControl) {
1909
+ this.ngControl.valueChanges?.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((val) => {
1910
+ // Find indices matching value
1911
+ this.updateSelectionFromValue(val);
1912
+ });
1913
+ }
1914
+ }
1915
+ updateSelectionFromValue(value) {
1916
+ const opts = this._options();
1917
+ const indices = [];
1918
+ if (this.isMulti()) {
1919
+ const valArray = Array.isArray(value) ? value : (value ? [value] : []);
1920
+ valArray.forEach((v) => {
1921
+ const idx = opts.findIndex(o => o.value == v); // weak equality for numbers/strings?
1922
+ if (idx !== -1)
1923
+ indices.push(idx);
1924
+ });
1925
+ }
1926
+ else {
1927
+ const idx = opts.findIndex(o => o.value == value);
1928
+ if (idx !== -1)
1929
+ indices.push(idx);
1930
+ }
1931
+ this._selectedIndices.set(indices);
1932
+ this.updateNativeSelect(false);
1933
+ }
1865
1934
  ngAfterViewInit() {
1866
1935
  this.loadOptionsFromSelect();
1867
1936
  this.loadInitialSelection();
@@ -2066,7 +2135,7 @@ class TngSelectDirective {
2066
2135
  // Update native select
2067
2136
  this.updateNativeSelect();
2068
2137
  }
2069
- updateNativeSelect() {
2138
+ updateNativeSelect(emitEvents = true) {
2070
2139
  const selectEl = this.el.nativeElement;
2071
2140
  const selectedIndices = this._selectedIndices();
2072
2141
  // Clear all selections
@@ -2079,10 +2148,12 @@ class TngSelectDirective {
2079
2148
  selectEl.options[idx].selected = true;
2080
2149
  }
2081
2150
  });
2082
- // Trigger change event
2083
- selectEl.dispatchEvent(new Event('change', { bubbles: true }));
2084
- // Also trigger input event for some frameworks
2085
- selectEl.dispatchEvent(new Event('input', { bubbles: true }));
2151
+ if (emitEvents) {
2152
+ // Trigger change event
2153
+ selectEl.dispatchEvent(new Event('change', { bubbles: true }));
2154
+ // Also trigger input event for some frameworks
2155
+ selectEl.dispatchEvent(new Event('input', { bubbles: true }));
2156
+ }
2086
2157
  }
2087
2158
  onDocumentClick = (event) => {
2088
2159
  const target = event.target;
@@ -2124,6 +2195,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImpor
2124
2195
  }] } });
2125
2196
 
2126
2197
  class TngSelectComponent {
2198
+ ngControl = inject(NgControl, { optional: true, self: true });
2127
2199
  // Inputs
2128
2200
  label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
2129
2201
  options = input.required(...(ngDevMode ? [{ debugName: "options" }] : []));
@@ -2155,18 +2227,20 @@ class TngSelectComponent {
2155
2227
  onChange = () => { };
2156
2228
  onTouched = () => { };
2157
2229
  constructor() {
2158
- // Sync model changes to CVA
2159
- effect(() => {
2160
- const val = this.value();
2161
- // Avoid circular updates if possible, but for now just emit
2162
- if (this.enableMulti()) {
2163
- this.onChange(val);
2164
- }
2165
- else {
2166
- this.onChange(val.length > 0 ? val[0] : null);
2167
- }
2168
- this.onTouched();
2169
- });
2230
+ if (this.ngControl) {
2231
+ this.ngControl.valueAccessor = this;
2232
+ }
2233
+ }
2234
+ onSelectionChange(newValues) {
2235
+ this.value.set(newValues);
2236
+ // Avoid circular updates if possible, but for now just emit
2237
+ if (this.enableMulti()) {
2238
+ this.onChange(newValues);
2239
+ }
2240
+ else {
2241
+ this.onChange(newValues.length > 0 ? newValues[0] : null);
2242
+ }
2243
+ this.onTouched();
2170
2244
  }
2171
2245
  onDisplayClick(event) {
2172
2246
  if (this.effectiveDisabled())
@@ -2199,23 +2273,11 @@ class TngSelectComponent {
2199
2273
  this.cvaDisabled.set(isDisabled);
2200
2274
  }
2201
2275
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2202
- 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: [
2203
- {
2204
- provide: NG_VALUE_ACCESSOR,
2205
- useExisting: forwardRef(() => TngSelectComponent),
2206
- multi: true
2207
- }
2208
- ], 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 });
2276
+ 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" }, 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 (selectedValuesChange)=\"onSelectionChange($event)\"\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 });
2209
2277
  }
2210
2278
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.0", ngImport: i0, type: TngSelectComponent, decorators: [{
2211
2279
  type: Component,
2212
- args: [{ selector: 'tng-select', standalone: true, imports: [CommonModule, FormsModule, TngSelectDirective], providers: [
2213
- {
2214
- provide: NG_VALUE_ACCESSOR,
2215
- useExisting: forwardRef(() => TngSelectComponent),
2216
- multi: true
2217
- }
2218
- ], 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"] }]
2280
+ args: [{ selector: 'tng-select', standalone: true, imports: [CommonModule, FormsModule, TngSelectDirective], 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 (selectedValuesChange)=\"onSelectionChange($event)\"\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"] }]
2219
2281
  }], 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 }] }] } });
2220
2282
 
2221
2283
  class TngSliderComponent {