@vsn-ux/ngx-gaia 0.8.8 → 0.9.0

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,17 +1,17 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, makeEnvironmentProviders, inject, ElementRef, HostAttributeToken, input, numberAttribute, computed, ViewEncapsulation, Component, NgModule, Injectable, booleanAttribute, ChangeDetectionStrategy, output, contentChild, forwardRef, Injector, signal, linkedSignal, Directive, model, HostListener, TemplateRef, NgZone, HostBinding, Input, DOCUMENT, effect, DestroyRef, afterNextRender, Renderer2, afterEveryRender, contentChildren, viewChild } from '@angular/core';
2
+ import { InjectionToken, makeEnvironmentProviders, inject, ElementRef, HostAttributeToken, input, numberAttribute, computed, ViewEncapsulation, Component, NgModule, Injectable, booleanAttribute, ChangeDetectionStrategy, output, contentChild, Directive, linkedSignal, signal, Injector, DestroyRef, effect, isSignal, forwardRef, model, HostListener, viewChild, TemplateRef, contentChildren, NgZone, HostBinding, Input, DOCUMENT, afterNextRender, Renderer2, afterEveryRender } from '@angular/core';
3
3
  import * as i1 from 'lucide-angular';
4
4
  import { LucideAngularModule, X, CircleCheck, TriangleAlert, OctagonAlert, Info, Check, Minus, ChevronUp, ChevronDown, CircleX } from 'lucide-angular';
5
- import { NG_VALUE_ACCESSOR, NgControl, NG_VALIDATORS, CheckboxRequiredValidator, RequiredValidator } from '@angular/forms';
5
+ import { NgForm, ControlContainer, NgControl, NG_VALUE_ACCESSOR, NG_VALIDATORS, CheckboxRequiredValidator, RequiredValidator } from '@angular/forms';
6
+ import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
7
+ import { NgTemplateOutlet } from '@angular/common';
6
8
  import * as i1$5 from '@angular/cdk/overlay';
7
9
  import { Overlay, createRepositionScrollStrategy, OverlayRef, CdkOverlayOrigin, OverlayModule } from '@angular/cdk/overlay';
8
10
  import { ComponentPortal } from '@angular/cdk/portal';
9
11
  import { Subject, takeUntil, map, merge, filter, Observable, isObservable } from 'rxjs';
10
12
  import { ESCAPE, hasModifierKey } from '@angular/cdk/keycodes';
11
- import { NgTemplateOutlet } from '@angular/common';
12
13
  import * as i1$1 from '@angular/cdk/menu';
13
14
  import { CdkMenu, CdkMenuItem, CdkMenuTrigger, MENU_SCROLL_STRATEGY } from '@angular/cdk/menu';
14
- import { toSignal, takeUntilDestroyed } from '@angular/core/rxjs-interop';
15
15
  import { Router, ResolveStart } from '@angular/router';
16
16
  import * as i1$2 from '@angular/cdk/a11y';
17
17
  import { CdkTrapFocus } from '@angular/cdk/a11y';
@@ -535,6 +535,118 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImpor
535
535
  }]
536
536
  }] });
537
537
 
538
+ class GaFormControlErrorsDirective {
539
+ customErrorsInput = input.required({
540
+ alias: 'gaFormControlErrors',
541
+ });
542
+ customErrors = computed(() => {
543
+ // for better API ergonomics, we ignore errors with null and undefined values
544
+ // this lets to bind custom errors directly without nasty if checks
545
+ // e.g. [gaFormControlErrors]="{ required: isEmpty ? true : null, noMatch: form.getError('noMatch') }"
546
+ return Object.entries(this.customErrorsInput()).reduce((acc, [key, value]) => {
547
+ if (value !== null && value !== undefined) {
548
+ acc[key] = value;
549
+ }
550
+ return acc;
551
+ }, {});
552
+ });
553
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFormControlErrorsDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
554
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.0.4", type: GaFormControlErrorsDirective, isStandalone: true, selector: "[gaFormControlErrors]", inputs: { customErrorsInput: { classPropertyName: "customErrorsInput", publicName: "gaFormControlErrors", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
555
+ }
556
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFormControlErrorsDirective, decorators: [{
557
+ type: Directive,
558
+ args: [{
559
+ selector: '[gaFormControlErrors]',
560
+ }]
561
+ }] });
562
+
563
+ const GA_FORM_CONTROL_ADAPTER = new InjectionToken('ga-form-control-adapter');
564
+ function injectNgControlState({ implicitChildNgControl, explicitNgControl, explicitNgForm, } = {}) {
565
+ const gaFormControlAdapter = inject(GA_FORM_CONTROL_ADAPTER, {
566
+ optional: true,
567
+ });
568
+ let ngControlErrors;
569
+ let ngControlTouched;
570
+ let ngControlDisabled;
571
+ let ngControlName;
572
+ let ngFormSubmitted;
573
+ if (gaFormControlAdapter) {
574
+ ngControlErrors = linkedSignal(() => gaFormControlAdapter.ngControlErrors());
575
+ ngControlTouched = linkedSignal(() => gaFormControlAdapter.ngControlTouched());
576
+ ngControlDisabled = linkedSignal(() => gaFormControlAdapter.ngControlDisabled());
577
+ ngControlName = linkedSignal(() => gaFormControlAdapter.ngControlName());
578
+ ngFormSubmitted = linkedSignal(() => gaFormControlAdapter.ngFormSubmitted());
579
+ }
580
+ else {
581
+ ngControlErrors = signal(null);
582
+ ngControlTouched = signal(false);
583
+ ngControlDisabled = signal(false);
584
+ ngControlName = signal(null);
585
+ ngFormSubmitted = signal(false);
586
+ const injector = inject(Injector);
587
+ const destroyRef = inject(DestroyRef);
588
+ const implicitNgForm = inject(NgForm, { optional: true });
589
+ const implicitControlContainer = inject(ControlContainer, {
590
+ optional: true,
591
+ });
592
+ const ngForm = explicitNgForm ??
593
+ implicitNgForm ??
594
+ (implicitControlContainer?.formDirective instanceof NgForm
595
+ ? implicitControlContainer.formDirective
596
+ : null);
597
+ let ngControlSubscription = null;
598
+ effect(() => {
599
+ if (ngControlSubscription) {
600
+ ngControlSubscription.unsubscribe();
601
+ ngControlSubscription = null;
602
+ }
603
+ if (isSignal(explicitNgControl)) {
604
+ explicitNgControl = explicitNgControl();
605
+ }
606
+ const ngControl = explicitNgControl ??
607
+ implicitChildNgControl?.() ??
608
+ injector.get(NgControl, null, { self: true, optional: true });
609
+ if (ngControl?.control) {
610
+ const updateStatuses = () => {
611
+ ngControlErrors.set(ngControl.errors);
612
+ ngControlTouched.set(!!ngControl.touched);
613
+ ngControlDisabled.set(!!ngControl.disabled);
614
+ ngControlName.set(ngControl.name);
615
+ };
616
+ updateStatuses();
617
+ ngControlSubscription = ngControl.control.events
618
+ .pipe(takeUntilDestroyed(destroyRef))
619
+ .subscribe(() => updateStatuses());
620
+ }
621
+ });
622
+ if (ngForm) {
623
+ ngFormSubmitted.set(ngForm.submitted);
624
+ ngForm.ngSubmit
625
+ .pipe(takeUntilDestroyed(destroyRef))
626
+ .subscribe(() => ngFormSubmitted.set(ngForm.submitted));
627
+ }
628
+ }
629
+ const customErrorsDirective = inject(GaFormControlErrorsDirective, {
630
+ optional: true,
631
+ });
632
+ const inError = signal(false);
633
+ const errors = signal({});
634
+ effect(() => {
635
+ errors.set({
636
+ ...ngControlErrors(),
637
+ ...(customErrorsDirective?.customErrors() ?? {}),
638
+ });
639
+ const hasErrors = Object.keys(errors()).length > 0;
640
+ inError.set(hasErrors && (ngControlTouched() || ngFormSubmitted()));
641
+ });
642
+ return {
643
+ inError: inError.asReadonly(),
644
+ errors: errors.asReadonly(),
645
+ disabled: ngControlDisabled.asReadonly(),
646
+ name: ngControlName.asReadonly(),
647
+ };
648
+ }
649
+
538
650
  const CHECKBOX_CONTROL_VALUE_ACCESSOR = {
539
651
  provide: NG_VALUE_ACCESSOR,
540
652
  useExisting: forwardRef(() => GaCheckboxComponent),
@@ -547,7 +659,7 @@ class GaCheckboxComponent {
547
659
  /** @ignore */
548
660
  _uniqueId = `ga-checkbox-${++nextUniqueId$8}`;
549
661
  /** @ignore */
550
- injector = inject(Injector);
662
+ implicitNgControlState = injectNgControlState();
551
663
  /** @ignore */
552
664
  tabindex = inject(new HostAttributeToken('tabindex'), {
553
665
  optional: true,
@@ -557,16 +669,15 @@ class GaCheckboxComponent {
557
669
  _onTouched;
558
670
  /** @ignore */
559
671
  _onModelChanged;
560
- /** @ignore */
561
- _invalidNgModel = signal(false);
562
- _ngModelName = signal(null);
563
672
  /** The value attribute of the native input element */
564
673
  value = input(null);
565
- disabled = input(false, {
674
+ disabledInput = input(false, {
566
675
  transform: booleanAttribute,
676
+ alias: 'disabled',
567
677
  });
568
- checked = input(false, {
678
+ checkedInput = input(false, {
569
679
  transform: booleanAttribute,
680
+ alias: 'checked',
570
681
  });
571
682
  nameInput = input(null, { alias: 'name' });
572
683
  id = input(null);
@@ -583,29 +694,22 @@ class GaCheckboxComponent {
583
694
  alias: 'aria-errormessage',
584
695
  });
585
696
  required = input(false, { transform: booleanAttribute });
586
- disabledModel = linkedSignal(() => this.disabled());
587
- checkedModel = linkedSignal(() => this.checked());
697
+ disabled = linkedSignal(() => this.disabledInput());
698
+ checked = linkedSignal(() => this.checkedInput());
588
699
  change = output();
589
700
  indeterminateChange = output();
590
701
  /** @ignore */
591
702
  inputId = computed(() => (this.id() ? this.id() : this._uniqueId));
592
703
  /** @ignore */
593
704
  name = computed(() => {
594
- return this.nameInput() ?? this._ngModelName() ?? this._uniqueId;
705
+ return (this.nameInput() ?? this.implicitNgControlState.name() ?? this._uniqueId);
595
706
  });
596
707
  /** @ignore */
597
708
  invalid = computed(() => {
598
709
  return this.ariaInvalid()
599
710
  ? this.ariaInvalid() === 'true'
600
- : this._invalidNgModel();
711
+ : this.implicitNgControlState.inError();
601
712
  });
602
- ngDoCheck() {
603
- const ngControl = this.injector.get(NgControl, null, { self: true });
604
- if (ngControl) {
605
- this._invalidNgModel.set(!!ngControl.invalid);
606
- this._ngModelName.set(ngControl.name);
607
- }
608
- }
609
713
  /** @ignore */
610
714
  onInputChange(event) {
611
715
  // We always have to stop propagation on the change event.
@@ -615,7 +719,7 @@ class GaCheckboxComponent {
615
719
  if (this.disabled()) {
616
720
  return;
617
721
  }
618
- this.checkedModel.set(!this.checkedModel());
722
+ this.checked.set(!this.checked());
619
723
  this.updateModel();
620
724
  }
621
725
  /** @ignore */
@@ -632,19 +736,19 @@ class GaCheckboxComponent {
632
736
  }
633
737
  /** @ignore */
634
738
  writeValue(value) {
635
- this.checkedModel.set(!!value);
739
+ this.checked.set(!!value);
636
740
  }
637
741
  /** @ignore */
638
742
  setDisabledState(isDisabled) {
639
- this.disabledModel.set(isDisabled);
743
+ this.disabled.set(isDisabled);
640
744
  }
641
745
  /** @ignore */
642
746
  updateModel() {
643
- this._onModelChanged?.(this.checkedModel());
644
- this.change.emit(this.checkedModel());
747
+ this._onModelChanged?.(this.checked());
748
+ this.change.emit(this.checked());
645
749
  }
646
750
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaCheckboxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
647
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.0.4", type: GaCheckboxComponent, isStandalone: true, selector: "ga-checkbox", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, nameInput: { classPropertyName: "nameInput", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, indeterminate: { classPropertyName: "indeterminate", publicName: "indeterminate", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "aria-labelledby", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedby: { classPropertyName: "ariaDescribedby", publicName: "aria-describedby", isSignal: true, isRequired: false, transformFunction: null }, ariaInvalid: { classPropertyName: "ariaInvalid", publicName: "aria-invalid", isSignal: true, isRequired: false, transformFunction: null }, ariaErrormessage: { classPropertyName: "ariaErrormessage", publicName: "aria-errormessage", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { change: "change", indeterminateChange: "indeterminateChange" }, host: { properties: { "class.ga-checkbox--invalid": "invalid()", "attr.id": "null", "attr.tabindex": "null", "attr.aria-label": "null", "attr.aria-labelledby": "null", "attr.aria-describedby": "null", "attr.aria-invalid": "null", "attr.aria-errormessage": "null" }, classAttribute: "ga-checkbox" }, providers: [CHECKBOX_CONTROL_VALUE_ACCESSOR], ngImport: i0, template: "<input\n type=\"checkbox\"\n class=\"ga-checkbox__native\"\n [attr.id]=\"inputId()\"\n [name]=\"name()\"\n [checked]=\"checkedModel()\"\n [indeterminate]=\"indeterminate()\"\n [disabled]=\"disabledModel()\"\n [required]=\"required()\"\n [attr.value]=\"value()\"\n [attr.tabindex]=\"tabindex\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledby()\"\n [attr.aria-describedby]=\"ariaDescribedby()\"\n [attr.aria-invalid]=\"ariaInvalid()\"\n [attr.aria-errormessage]=\"ariaErrormessage()\"\n (change)=\"onInputChange($event)\"\n (blur)=\"onBlur()\"\n/>\n<div class=\"ga-checkbox__marker\">\n <lucide-icon\n [img]=\"icons.Check\"\n class=\"ga-checkbox__marker__indicator-checked\"\n [size]=\"12\"\n [strokeWidth]=\"2\"\n [absoluteStrokeWidth]=\"true\"\n />\n <lucide-icon\n [img]=\"icons.Minus\"\n class=\"ga-checkbox__marker__indicator-indeterminate\"\n [size]=\"12\"\n [strokeWidth]=\"2\"\n [absoluteStrokeWidth]=\"true\"\n />\n</div>\n\n<label class=\"ga-checkbox__label\" [attr.for]=\"inputId()\"\n ><ng-content></ng-content\n></label>\n", dependencies: [{ kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
751
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.0.4", type: GaCheckboxComponent, isStandalone: true, selector: "ga-checkbox", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, checkedInput: { classPropertyName: "checkedInput", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, nameInput: { classPropertyName: "nameInput", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, indeterminate: { classPropertyName: "indeterminate", publicName: "indeterminate", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "aria-labelledby", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedby: { classPropertyName: "ariaDescribedby", publicName: "aria-describedby", isSignal: true, isRequired: false, transformFunction: null }, ariaInvalid: { classPropertyName: "ariaInvalid", publicName: "aria-invalid", isSignal: true, isRequired: false, transformFunction: null }, ariaErrormessage: { classPropertyName: "ariaErrormessage", publicName: "aria-errormessage", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { change: "change", indeterminateChange: "indeterminateChange" }, host: { properties: { "class.ga-checkbox--invalid": "invalid()", "attr.id": "null", "attr.tabindex": "null", "attr.aria-label": "null", "attr.aria-labelledby": "null", "attr.aria-describedby": "null", "attr.aria-invalid": "null", "attr.aria-errormessage": "null" }, classAttribute: "ga-checkbox" }, providers: [CHECKBOX_CONTROL_VALUE_ACCESSOR], ngImport: i0, template: "<input\n type=\"checkbox\"\n class=\"ga-checkbox__native\"\n [attr.id]=\"inputId()\"\n [name]=\"name()\"\n [checked]=\"checked()\"\n [indeterminate]=\"indeterminate()\"\n [disabled]=\"disabled()\"\n [required]=\"required()\"\n [attr.value]=\"value()\"\n [attr.tabindex]=\"tabindex\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledby()\"\n [attr.aria-describedby]=\"ariaDescribedby()\"\n [attr.aria-invalid]=\"ariaInvalid()\"\n [attr.aria-errormessage]=\"ariaErrormessage()\"\n (change)=\"onInputChange($event)\"\n (blur)=\"onBlur()\"\n/>\n<div class=\"ga-checkbox__marker\">\n <lucide-icon\n [img]=\"icons.Check\"\n class=\"ga-checkbox__marker__indicator-checked\"\n [size]=\"12\"\n [strokeWidth]=\"2\"\n [absoluteStrokeWidth]=\"true\"\n />\n <lucide-icon\n [img]=\"icons.Minus\"\n class=\"ga-checkbox__marker__indicator-indeterminate\"\n [size]=\"12\"\n [strokeWidth]=\"2\"\n [absoluteStrokeWidth]=\"true\"\n />\n</div>\n\n<label class=\"ga-checkbox__label\" [attr.for]=\"inputId()\"\n ><ng-content></ng-content\n></label>\n", dependencies: [{ kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i1.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
648
752
  }
649
753
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaCheckboxComponent, decorators: [{
650
754
  type: Component,
@@ -658,7 +762,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImpor
658
762
  '[attr.aria-describedby]': 'null',
659
763
  '[attr.aria-invalid]': 'null',
660
764
  '[attr.aria-errormessage]': 'null',
661
- }, template: "<input\n type=\"checkbox\"\n class=\"ga-checkbox__native\"\n [attr.id]=\"inputId()\"\n [name]=\"name()\"\n [checked]=\"checkedModel()\"\n [indeterminate]=\"indeterminate()\"\n [disabled]=\"disabledModel()\"\n [required]=\"required()\"\n [attr.value]=\"value()\"\n [attr.tabindex]=\"tabindex\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledby()\"\n [attr.aria-describedby]=\"ariaDescribedby()\"\n [attr.aria-invalid]=\"ariaInvalid()\"\n [attr.aria-errormessage]=\"ariaErrormessage()\"\n (change)=\"onInputChange($event)\"\n (blur)=\"onBlur()\"\n/>\n<div class=\"ga-checkbox__marker\">\n <lucide-icon\n [img]=\"icons.Check\"\n class=\"ga-checkbox__marker__indicator-checked\"\n [size]=\"12\"\n [strokeWidth]=\"2\"\n [absoluteStrokeWidth]=\"true\"\n />\n <lucide-icon\n [img]=\"icons.Minus\"\n class=\"ga-checkbox__marker__indicator-indeterminate\"\n [size]=\"12\"\n [strokeWidth]=\"2\"\n [absoluteStrokeWidth]=\"true\"\n />\n</div>\n\n<label class=\"ga-checkbox__label\" [attr.for]=\"inputId()\"\n ><ng-content></ng-content\n></label>\n" }]
765
+ }, template: "<input\n type=\"checkbox\"\n class=\"ga-checkbox__native\"\n [attr.id]=\"inputId()\"\n [name]=\"name()\"\n [checked]=\"checked()\"\n [indeterminate]=\"indeterminate()\"\n [disabled]=\"disabled()\"\n [required]=\"required()\"\n [attr.value]=\"value()\"\n [attr.tabindex]=\"tabindex\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledby()\"\n [attr.aria-describedby]=\"ariaDescribedby()\"\n [attr.aria-invalid]=\"ariaInvalid()\"\n [attr.aria-errormessage]=\"ariaErrormessage()\"\n (change)=\"onInputChange($event)\"\n (blur)=\"onBlur()\"\n/>\n<div class=\"ga-checkbox__marker\">\n <lucide-icon\n [img]=\"icons.Check\"\n class=\"ga-checkbox__marker__indicator-checked\"\n [size]=\"12\"\n [strokeWidth]=\"2\"\n [absoluteStrokeWidth]=\"true\"\n />\n <lucide-icon\n [img]=\"icons.Minus\"\n class=\"ga-checkbox__marker__indicator-indeterminate\"\n [size]=\"12\"\n [strokeWidth]=\"2\"\n [absoluteStrokeWidth]=\"true\"\n />\n</div>\n\n<label class=\"ga-checkbox__label\" [attr.for]=\"inputId()\"\n ><ng-content></ng-content\n></label>\n" }]
662
766
  }] });
663
767
 
664
768
  const GA_CHECKBOX_REQUIRED_VALIDATOR = {
@@ -824,101 +928,52 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImpor
824
928
  }]
825
929
  }] });
826
930
 
827
- class GaInputComponent {
828
- implicitNgControl = contentChild(NgControl);
829
- implicitInvalid = signal(false);
830
- invalidInput = input(null, { transform: booleanAttribute });
831
- invalid = computed(() => {
832
- return this.invalidInput() ?? this.implicitInvalid();
833
- });
834
- ngDoCheck() {
835
- // we can rely on computed because `ivalid` of NgControl is not a signal, yet
836
- const implicitNgControl = this.implicitNgControl();
837
- if (implicitNgControl) {
838
- this.implicitInvalid.set(!!implicitNgControl.invalid && !!implicitNgControl.dirty);
839
- }
840
- }
841
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
842
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.0.4", type: GaInputComponent, isStandalone: true, selector: "ga-input", inputs: { invalidInput: { classPropertyName: "invalidInput", publicName: "invalidInput", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.ga-input--invalid": "invalid()" }, classAttribute: "ga-input" }, queries: [{ propertyName: "implicitNgControl", first: true, predicate: NgControl, descendants: true, isSignal: true }], ngImport: i0, template: `<ng-content />`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
843
- }
844
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaInputComponent, decorators: [{
845
- type: Component,
846
- args: [{
847
- selector: 'ga-input',
848
- template: `<ng-content />`,
849
- changeDetection: ChangeDetectionStrategy.OnPush,
850
- host: {
851
- class: 'ga-input',
852
- '[class.ga-input--invalid]': 'invalid()',
853
- },
854
- }]
855
- }] });
856
-
857
- const GA_FORM_CONTROL = new InjectionToken('ga-form-control');
858
- class GaFormControlDirective {
859
- _formControlId = input(undefined, {
860
- alias: 'gaFormControl',
861
- });
862
- _formControlDisabled = input(undefined, {
863
- alias: 'gaFormControlDisabled',
864
- });
865
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFormControlDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
866
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.0.4", type: GaFormControlDirective, isStandalone: true, selector: "[gaFormControl]", inputs: { _formControlId: { classPropertyName: "_formControlId", publicName: "gaFormControl", isSignal: true, isRequired: false, transformFunction: null }, _formControlDisabled: { classPropertyName: "_formControlDisabled", publicName: "gaFormControlDisabled", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
867
- { provide: GA_FORM_CONTROL, useExisting: GaFormControlDirective },
868
- ], ngImport: i0 });
931
+ class GaFormFieldConnector {
932
+ controlDisabled = signal(false);
933
+ controlId = signal(null);
934
+ labelId = signal(null);
935
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFormFieldConnector, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
936
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFormFieldConnector });
869
937
  }
870
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFormControlDirective, decorators: [{
871
- type: Directive,
872
- args: [{
873
- selector: '[gaFormControl]',
874
- providers: [
875
- { provide: GA_FORM_CONTROL, useExisting: GaFormControlDirective },
876
- ],
877
- }]
938
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFormFieldConnector, decorators: [{
939
+ type: Injectable
878
940
  }] });
879
941
 
880
942
  let nextUniqueId$7 = 0;
881
943
  class GaInputDirective {
882
944
  uniqueId = `ga-input-${++nextUniqueId$7}`;
883
- implicitNgControl = inject(NgControl, {
945
+ formFieldConnector = inject(GaFormFieldConnector, {
884
946
  optional: true,
885
- self: true,
886
947
  });
887
948
  hasWrapper = inject(GaInputComponent, { optional: true });
888
- implicitInvalid = signal(false);
889
- implicitErrors = signal(null);
949
+ implicitNgControlState = injectNgControlState();
890
950
  invalidInput = input(null, {
891
951
  alias: 'invalid',
892
952
  transform: booleanAttribute,
893
953
  });
894
954
  idInput = input(undefined, { alias: 'id' });
895
- disabledInput = input(false, {
955
+ disabledInput = input(undefined, {
896
956
  alias: 'disabled',
897
957
  transform: booleanAttribute,
898
958
  });
899
959
  invalid = computed(() => {
900
- return this.invalidInput() ?? this.implicitInvalid();
960
+ return this.invalidInput() ?? this.implicitNgControlState.inError();
901
961
  });
902
962
  id = computed(() => {
903
963
  return this.idInput() ?? this.uniqueId;
904
964
  });
905
- disabled = linkedSignal(() => this.disabledInput());
906
- errors = this.implicitErrors.asReadonly();
907
- _formControlId = this.id;
908
- _formControlDisabled = computed(() => this.disabled());
909
- ngDoCheck() {
910
- if (this.hasWrapper)
911
- return;
912
- // we can rely on computed because `ivalid` of NgControl is not a signal, yet
913
- const implicitNgControl = this.implicitNgControl;
914
- if (implicitNgControl) {
915
- this.implicitInvalid.set(!!implicitNgControl.invalid && !!implicitNgControl.dirty);
916
- this.implicitErrors.set(implicitNgControl.errors);
917
- this.disabled.set(!!implicitNgControl.disabled);
965
+ disabled = computed(() => {
966
+ return this.disabledInput() ?? this.implicitNgControlState.disabled();
967
+ });
968
+ constructor() {
969
+ const formFieldConnector = this.formFieldConnector;
970
+ if (formFieldConnector) {
971
+ effect(() => formFieldConnector.controlDisabled.set(this.disabled()));
972
+ effect(() => formFieldConnector.controlId.set(this.id()));
918
973
  }
919
974
  }
920
975
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaInputDirective, deps: [], target: i0.ɵɵFactoryTarget.Component });
921
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.0.4", type: GaInputDirective, isStandalone: true, selector: "[gaInput]", inputs: { invalidInput: { classPropertyName: "invalidInput", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, idInput: { classPropertyName: "idInput", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.id": "id()", "class.ga-input": "!hasWrapper", "class.ga-input--invalid": "!hasWrapper && invalid()" } }, providers: [{ provide: GA_FORM_CONTROL, useExisting: GaInputDirective }], ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
976
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.0.4", type: GaInputDirective, isStandalone: true, selector: "[gaInput]", inputs: { invalidInput: { classPropertyName: "invalidInput", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, idInput: { classPropertyName: "idInput", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.id": "id()", "class.ga-input": "!hasWrapper", "class.ga-input--invalid": "!hasWrapper && invalid()" } }, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
922
977
  }
923
978
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaInputDirective, decorators: [{
924
979
  type: Component,
@@ -932,7 +987,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImpor
932
987
  '[class.ga-input]': '!hasWrapper',
933
988
  '[class.ga-input--invalid]': '!hasWrapper && invalid()',
934
989
  },
935
- providers: [{ provide: GA_FORM_CONTROL, useExisting: GaInputDirective }],
990
+ }]
991
+ }], ctorParameters: () => [] });
992
+
993
+ class GaInputComponent {
994
+ gaInput = contentChild.required(GaInputDirective);
995
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
996
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.0.4", type: GaInputComponent, isStandalone: true, selector: "ga-input", host: { properties: { "class.ga-input--invalid": "gaInput().invalid()" }, classAttribute: "ga-input" }, queries: [{ propertyName: "gaInput", first: true, predicate: GaInputDirective, descendants: true, isSignal: true }], ngImport: i0, template: `<ng-content />`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
997
+ }
998
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaInputComponent, decorators: [{
999
+ type: Component,
1000
+ args: [{
1001
+ selector: 'ga-input',
1002
+ template: `<ng-content />`,
1003
+ changeDetection: ChangeDetectionStrategy.OnPush,
1004
+ host: {
1005
+ class: 'ga-input',
1006
+ '[class.ga-input--invalid]': 'gaInput().invalid()',
1007
+ },
936
1008
  }]
937
1009
  }] });
938
1010
 
@@ -949,19 +1021,156 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImpor
949
1021
  }]
950
1022
  }] });
951
1023
 
1024
+ const GA_FORM_FIELD_ID = new InjectionToken('ga-form-field-id');
1025
+
1026
+ class GaFormControlDirective {
1027
+ formFieldId = inject(GA_FORM_FIELD_ID, { optional: true });
1028
+ ngControlInput = input(undefined, {
1029
+ alias: 'gaFormControl',
1030
+ });
1031
+ explicitNgControl = computed(() => {
1032
+ const ngControl = this.ngControlInput();
1033
+ if (ngControl instanceof NgControl) {
1034
+ return ngControl;
1035
+ }
1036
+ return null;
1037
+ });
1038
+ ngControlState = injectNgControlState({
1039
+ explicitNgControl: this.explicitNgControl,
1040
+ });
1041
+ inError = this.ngControlState.inError;
1042
+ errors = this.ngControlState.errors;
1043
+ ariaErrorMessageId = computed(() => {
1044
+ if (!this.formFieldId || !this.inError()) {
1045
+ return null;
1046
+ }
1047
+ return `${this.formFieldId}-callout`;
1048
+ });
1049
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFormControlDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1050
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.0.4", type: GaFormControlDirective, isStandalone: true, selector: "[gaFormControl]", inputs: { ngControlInput: { classPropertyName: "ngControlInput", publicName: "gaFormControl", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.aria-invalid": "inError() ? \"true\" : null", "attr.aria-errormessage": "ariaErrorMessageId()" } }, exportAs: ["gaFormControl"], ngImport: i0 });
1051
+ }
1052
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFormControlDirective, decorators: [{
1053
+ type: Directive,
1054
+ args: [{
1055
+ exportAs: 'gaFormControl',
1056
+ selector: '[gaFormControl]',
1057
+ host: {
1058
+ '[attr.aria-invalid]': 'inError() ? "true" : null',
1059
+ '[attr.aria-errormessage]': 'ariaErrorMessageId()',
1060
+ },
1061
+ }]
1062
+ }] });
1063
+
1064
+ class GaFieldCalloutComponent {
1065
+ icons = { OctagonAlert };
1066
+ formField = inject(GaFormFieldComponent);
1067
+ id = this.formField.uniqueId + '-callout';
1068
+ shouldShowError = computed(() => {
1069
+ const formControl = this.formField.formControl();
1070
+ if (!formControl) {
1071
+ return false;
1072
+ }
1073
+ return formControl.inError() && this.overlappingErrors().length > 0;
1074
+ });
1075
+ overlappingErrors = computed(() => {
1076
+ const formControl = this.formField.formControl();
1077
+ if (!formControl) {
1078
+ return [];
1079
+ }
1080
+ const registeredErrors = this.formField
1081
+ .fieldErrors()
1082
+ .filter((err) => err.key());
1083
+ const controlErrorKeys = Object.keys(formControl.errors());
1084
+ return registeredErrors
1085
+ .filter((err) => controlErrorKeys.includes(err.key()))
1086
+ .map((err) => {
1087
+ const errorKey = err.key();
1088
+ return {
1089
+ key: errorKey,
1090
+ templateRef: err.templateRef,
1091
+ error: formControl.errors()[errorKey],
1092
+ };
1093
+ });
1094
+ });
1095
+ hasCallout = computed(() => !!this.formField.fieldInfo() || this.shouldShowError());
1096
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFieldCalloutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1097
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.4", type: GaFieldCalloutComponent, isStandalone: true, selector: "ga-field-callout", host: { properties: { "attr.id": "id", "style.display": "hasCallout() ? null : \"none\"" }, classAttribute: "ga-form-field__info" }, ngImport: i0, template: "@if (shouldShowError()) {\n <ga-icon\n [icon]=\"icons.OctagonAlert\"\n class=\"ga-icon\"\n style=\"color: var(--ga-color-icon-error)\"\n size=\"16\"\n />\n <div>\n @for (error of overlappingErrors(); track error.key; let last = $last) {\n <span\n ><ng-container\n [ngTemplateOutlet]=\"error.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: error.error }\"\n />&nbsp;</span\n >\n }\n </div>\n} @else if (formField.fieldInfo()) {\n <ng-container [ngTemplateOutlet]=\"formField.fieldInfo()!.templateRef()\" />\n}\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: GaIconModule }, { kind: "component", type: GaIconComponent, selector: "ga-icon", inputs: ["icon", "size", "color", "strokeWidth"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1098
+ }
1099
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFieldCalloutComponent, decorators: [{
1100
+ type: Component,
1101
+ args: [{ selector: 'ga-field-callout', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgTemplateOutlet, GaIconModule], host: {
1102
+ class: 'ga-form-field__info',
1103
+ '[attr.id]': 'id',
1104
+ '[style.display]': 'hasCallout() ? null : "none"',
1105
+ }, template: "@if (shouldShowError()) {\n <ga-icon\n [icon]=\"icons.OctagonAlert\"\n class=\"ga-icon\"\n style=\"color: var(--ga-color-icon-error)\"\n size=\"16\"\n />\n <div>\n @for (error of overlappingErrors(); track error.key; let last = $last) {\n <span\n ><ng-container\n [ngTemplateOutlet]=\"error.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: error.error }\"\n />&nbsp;</span\n >\n }\n </div>\n} @else if (formField.fieldInfo()) {\n <ng-container [ngTemplateOutlet]=\"formField.fieldInfo()!.templateRef()\" />\n}\n" }]
1106
+ }] });
1107
+
1108
+ class GaFieldInfoComponent {
1109
+ templateRef = viewChild.required(TemplateRef);
1110
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFieldInfoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1111
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.0.4", type: GaFieldInfoComponent, isStandalone: true, selector: "ga-info", host: { properties: { "style.display": "\"none\"" } }, viewQueries: [{ propertyName: "templateRef", first: true, predicate: TemplateRef, descendants: true, isSignal: true }], ngImport: i0, template: `<ng-template><ng-content /></ng-template>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
1112
+ }
1113
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFieldInfoComponent, decorators: [{
1114
+ type: Component,
1115
+ args: [{
1116
+ selector: 'ga-info',
1117
+ template: `<ng-template><ng-content /></ng-template>`,
1118
+ changeDetection: ChangeDetectionStrategy.OnPush,
1119
+ host: {
1120
+ '[style.display]': '"none"',
1121
+ },
1122
+ }]
1123
+ }] });
1124
+
1125
+ class GaFieldErrorDirective {
1126
+ templateRef = inject(TemplateRef, { self: true });
1127
+ key = input.required({ alias: 'gaError' });
1128
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFieldErrorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1129
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.0.4", type: GaFieldErrorDirective, isStandalone: true, selector: "[gaError]", inputs: { key: { classPropertyName: "key", publicName: "gaError", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
1130
+ }
1131
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFieldErrorDirective, decorators: [{
1132
+ type: Directive,
1133
+ args: [{
1134
+ selector: '[gaError]',
1135
+ }]
1136
+ }] });
1137
+
952
1138
  let nextUniqueId$6 = 0;
953
1139
  class GaFormFieldComponent {
954
- uniqueId = `ga-form-field-${++nextUniqueId$6}`;
955
- disabled = input(undefined, { transform: booleanAttribute });
956
- formControl = contentChild(GA_FORM_CONTROL, { descendants: true });
1140
+ uniqueId = inject(GA_FORM_FIELD_ID);
1141
+ formFieldConnector = inject(GaFormFieldConnector);
1142
+ disabledInput = input(undefined, {
1143
+ alias: 'disabled',
1144
+ transform: booleanAttribute,
1145
+ });
1146
+ disabled = computed(() => {
1147
+ return this.disabledInput() ?? this.formFieldConnector.controlDisabled();
1148
+ });
1149
+ formControl = contentChild(GaFormControlDirective, {
1150
+ descendants: true,
1151
+ });
1152
+ fieldInfo = contentChild(GaFieldInfoComponent);
1153
+ fieldErrors = contentChildren(GaFieldErrorDirective);
957
1154
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFormFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
958
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.0.4", type: GaFormFieldComponent, isStandalone: true, selector: "ga-form-field", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "ga-form-field" }, queries: [{ propertyName: "formControl", first: true, predicate: GA_FORM_CONTROL, descendants: true, isSignal: true }], exportAs: ["gaFormField"], ngImport: i0, template: "<ng-content />\n", changeDetection: i0.ChangeDetectionStrategy.OnPush });
1155
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.0.4", type: GaFormFieldComponent, isStandalone: true, selector: "ga-form-field", inputs: { disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "ga-form-field" }, providers: [
1156
+ {
1157
+ provide: GA_FORM_FIELD_ID,
1158
+ useFactory: () => `ga-form-field-${++nextUniqueId$6}`,
1159
+ },
1160
+ GaFormFieldConnector,
1161
+ ], queries: [{ propertyName: "formControl", first: true, predicate: GaFormControlDirective, descendants: true, isSignal: true }, { propertyName: "fieldInfo", first: true, predicate: GaFieldInfoComponent, descendants: true, isSignal: true }, { propertyName: "fieldErrors", predicate: GaFieldErrorDirective, isSignal: true }], exportAs: ["gaFormField"], ngImport: i0, template: "<ng-content select=\"ga-label\" />\n<ng-content />\n<ga-field-callout />\n", dependencies: [{ kind: "component", type: GaFieldCalloutComponent, selector: "ga-field-callout" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
959
1162
  }
960
1163
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFormFieldComponent, decorators: [{
961
1164
  type: Component,
962
- args: [{ selector: 'ga-form-field', exportAs: 'gaFormField', changeDetection: ChangeDetectionStrategy.OnPush, host: {
1165
+ args: [{ selector: 'ga-form-field', exportAs: 'gaFormField', changeDetection: ChangeDetectionStrategy.OnPush, imports: [GaFieldCalloutComponent], host: {
963
1166
  class: 'ga-form-field',
964
- }, template: "<ng-content />\n" }]
1167
+ }, providers: [
1168
+ {
1169
+ provide: GA_FORM_FIELD_ID,
1170
+ useFactory: () => `ga-form-field-${++nextUniqueId$6}`,
1171
+ },
1172
+ GaFormFieldConnector,
1173
+ ], template: "<ng-content select=\"ga-label\" />\n<ng-content />\n<ga-field-callout />\n" }]
965
1174
  }] });
966
1175
 
967
1176
  let nextUniqueId$5 = 0;
@@ -1356,24 +1565,37 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImpor
1356
1565
  class GaFieldLabelComponent {
1357
1566
  document = inject(DOCUMENT);
1358
1567
  formField = inject(GaFormFieldComponent);
1568
+ formFieldConnector = inject(GaFormFieldConnector, {
1569
+ optional: true,
1570
+ });
1359
1571
  uniqueId = this.formField.uniqueId + '-label';
1360
1572
  for = input();
1361
1573
  definition = input(null);
1362
1574
  state = input();
1363
- controlId = computed(() => {
1364
- return this.for() ?? this.formField.formControl()?._formControlId();
1575
+ idInput = input(undefined, { alias: 'id' });
1576
+ id = computed(() => {
1577
+ return this.idInput() ?? this.uniqueId;
1365
1578
  });
1366
- disabled = computed(() => {
1367
- return (this.formField.disabled() ??
1368
- !!this.formField.formControl()?._formControlDisabled());
1579
+ controlId = computed(() => {
1580
+ return this.for() ?? this.formFieldConnector?.controlId();
1369
1581
  });
1370
1582
  controlElement = computed(() => {
1371
- const control = this.document.querySelector(`#${this.controlId()}`);
1583
+ const controlId = this.controlId();
1584
+ if (!controlId) {
1585
+ return null;
1586
+ }
1587
+ const control = this.document.querySelector(`#${CSS.escape(controlId)}`);
1372
1588
  if (control instanceof HTMLElement) {
1373
1589
  return control;
1374
1590
  }
1375
1591
  return null;
1376
1592
  });
1593
+ constructor() {
1594
+ const formFieldConnector = this.formFieldConnector;
1595
+ if (formFieldConnector) {
1596
+ effect(() => formFieldConnector.labelId.set(this.id()));
1597
+ }
1598
+ }
1377
1599
  focusControl() {
1378
1600
  const control = this.controlElement();
1379
1601
  // only focus custom elements as native elements already
@@ -1383,41 +1605,24 @@ class GaFieldLabelComponent {
1383
1605
  }
1384
1606
  }
1385
1607
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFieldLabelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1386
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.4", type: GaFieldLabelComponent, isStandalone: true, selector: "ga-label", inputs: { for: { classPropertyName: "for", publicName: "for", isSignal: true, isRequired: false, transformFunction: null }, definition: { classPropertyName: "definition", publicName: "definition", isSignal: true, isRequired: false, transformFunction: null }, state: { classPropertyName: "state", publicName: "state", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events -->\n<label\n [attr.id]=\"uniqueId\"\n [attr.for]=\"controlId()\"\n class=\"ga-form-field__label\"\n [class.ga-form-field__label--defined]=\"!!definition()\"\n [class.ga-form-field__label--disabled]=\"\n !!formField.formControl()?._formControlDisabled()\n \"\n (click)=\"focusControl()\"\n [attr.tabindex]=\"definition() ? 0 : -1\"\n>\n <span\n class=\"ga-form-field__label-text\"\n [gaTooltip]=\"definition()\"\n gaTooltipPlacement=\"top-start\"\n ><ng-content\n /></span>\n @if (state()) {\n <span class=\"ga-form-field__label-state\">{{ state() }}</span>\n }\n</label>\n", dependencies: [{ kind: "ngmodule", type: GaTooltipModule }, { kind: "directive", type: GaTooltipDirective, selector: "[gaTooltip]", inputs: ["gaTooltip", "gaTooltipDisabled", "gaTooltipControlMode", "gaTooltipShowControlMode", "gaTooltipHideControlMode", "gaTooltipOffsetSize", "gaTooltipPlacement"], exportAs: ["gaTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1608
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.4", type: GaFieldLabelComponent, isStandalone: true, selector: "ga-label", inputs: { for: { classPropertyName: "for", publicName: "for", isSignal: true, isRequired: false, transformFunction: null }, definition: { classPropertyName: "definition", publicName: "definition", isSignal: true, isRequired: false, transformFunction: null }, state: { classPropertyName: "state", publicName: "state", isSignal: true, isRequired: false, transformFunction: null }, idInput: { classPropertyName: "idInput", publicName: "id", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.id": "null" } }, ngImport: i0, template: "<!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events -->\n<label\n [attr.id]=\"id()\"\n [attr.for]=\"controlId()\"\n class=\"ga-form-field__label\"\n [class.ga-form-field__label--defined]=\"!!definition()\"\n [class.ga-form-field__label--disabled]=\"formField.disabled()\"\n (click)=\"focusControl()\"\n [attr.tabindex]=\"definition() ? 0 : -1\"\n>\n <span\n class=\"ga-form-field__label-text\"\n [gaTooltip]=\"definition()\"\n gaTooltipPlacement=\"top-start\"\n ><ng-content\n /></span>\n @if (state()) {\n <span class=\"ga-form-field__label-state\">{{ state() }}</span>\n }\n</label>\n", dependencies: [{ kind: "ngmodule", type: GaTooltipModule }, { kind: "directive", type: GaTooltipDirective, selector: "[gaTooltip]", inputs: ["gaTooltip", "gaTooltipDisabled", "gaTooltipControlMode", "gaTooltipShowControlMode", "gaTooltipHideControlMode", "gaTooltipOffsetSize", "gaTooltipPlacement"], exportAs: ["gaTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1387
1609
  }
1388
1610
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFieldLabelComponent, decorators: [{
1389
1611
  type: Component,
1390
- args: [{ selector: 'ga-label', imports: [GaTooltipModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events -->\n<label\n [attr.id]=\"uniqueId\"\n [attr.for]=\"controlId()\"\n class=\"ga-form-field__label\"\n [class.ga-form-field__label--defined]=\"!!definition()\"\n [class.ga-form-field__label--disabled]=\"\n !!formField.formControl()?._formControlDisabled()\n \"\n (click)=\"focusControl()\"\n [attr.tabindex]=\"definition() ? 0 : -1\"\n>\n <span\n class=\"ga-form-field__label-text\"\n [gaTooltip]=\"definition()\"\n gaTooltipPlacement=\"top-start\"\n ><ng-content\n /></span>\n @if (state()) {\n <span class=\"ga-form-field__label-state\">{{ state() }}</span>\n }\n</label>\n" }]
1391
- }] });
1392
-
1393
- class GaFieldInfoComponent {
1394
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFieldInfoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1395
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.0.4", type: GaFieldInfoComponent, isStandalone: true, selector: "ga-info", host: { classAttribute: "ga-form-field__info" }, ngImport: i0, template: `<ng-content />`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
1396
- }
1397
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFieldInfoComponent, decorators: [{
1398
- type: Component,
1399
- args: [{
1400
- selector: 'ga-info',
1401
- template: `<ng-content />`,
1402
- changeDetection: ChangeDetectionStrategy.OnPush,
1403
- host: {
1404
- class: 'ga-form-field__info',
1405
- },
1406
- }]
1407
- }] });
1612
+ args: [{ selector: 'ga-label', imports: [GaTooltipModule], changeDetection: ChangeDetectionStrategy.OnPush, host: {
1613
+ '[attr.id]': 'null',
1614
+ }, template: "<!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events -->\n<label\n [attr.id]=\"id()\"\n [attr.for]=\"controlId()\"\n class=\"ga-form-field__label\"\n [class.ga-form-field__label--defined]=\"!!definition()\"\n [class.ga-form-field__label--disabled]=\"formField.disabled()\"\n (click)=\"focusControl()\"\n [attr.tabindex]=\"definition() ? 0 : -1\"\n>\n <span\n class=\"ga-form-field__label-text\"\n [gaTooltip]=\"definition()\"\n gaTooltipPlacement=\"top-start\"\n ><ng-content\n /></span>\n @if (state()) {\n <span class=\"ga-form-field__label-state\">{{ state() }}</span>\n }\n</label>\n" }]
1615
+ }], ctorParameters: () => [] });
1408
1616
 
1409
1617
  class GaLabelledByFormFieldDirective {
1410
- formField = inject(GaFormFieldComponent, {
1618
+ formFieldConnector = inject(GaFormFieldConnector, {
1411
1619
  optional: true,
1412
1620
  });
1413
1621
  ariaLabelledBy = input(null, {
1414
1622
  alias: 'aria-labelledby',
1415
1623
  });
1416
1624
  labelledBy = computed(() => {
1417
- const formFieldLabelledBy = this.formField
1418
- ? this.formField.uniqueId + '-label'
1419
- : null;
1420
- return this.ariaLabelledBy() ?? formFieldLabelledBy;
1625
+ return this.ariaLabelledBy() ?? this.formFieldConnector?.labelId();
1421
1626
  });
1422
1627
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaLabelledByFormFieldDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1423
1628
  static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.0.4", type: GaLabelledByFormFieldDirective, isStandalone: true, selector: "[gaLabelledByFormField]", inputs: { ariaLabelledBy: { classPropertyName: "ariaLabelledBy", publicName: "aria-labelledby", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.aria-labelledby": "labelledBy()" } }, ngImport: i0 });
@@ -1437,11 +1642,15 @@ class GaFormFieldModule {
1437
1642
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.0.4", ngImport: i0, type: GaFormFieldModule, imports: [GaFormFieldComponent,
1438
1643
  GaFieldLabelComponent,
1439
1644
  GaFieldInfoComponent,
1645
+ GaFieldErrorDirective,
1646
+ GaFormControlErrorsDirective,
1440
1647
  GaFormControlDirective], exports: [GaFormFieldComponent,
1441
1648
  GaFieldLabelComponent,
1442
1649
  GaFieldInfoComponent,
1650
+ GaFieldErrorDirective,
1651
+ GaFormControlErrorsDirective,
1443
1652
  GaFormControlDirective] });
1444
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFormFieldModule });
1653
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFormFieldModule, imports: [GaFormFieldComponent] });
1445
1654
  }
1446
1655
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFormFieldModule, decorators: [{
1447
1656
  type: NgModule,
@@ -1450,12 +1659,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImpor
1450
1659
  GaFormFieldComponent,
1451
1660
  GaFieldLabelComponent,
1452
1661
  GaFieldInfoComponent,
1662
+ GaFieldErrorDirective,
1663
+ GaFormControlErrorsDirective,
1453
1664
  GaFormControlDirective,
1454
1665
  ],
1455
1666
  exports: [
1456
1667
  GaFormFieldComponent,
1457
1668
  GaFieldLabelComponent,
1458
1669
  GaFieldInfoComponent,
1670
+ GaFieldErrorDirective,
1671
+ GaFormControlErrorsDirective,
1459
1672
  GaFormControlDirective,
1460
1673
  ],
1461
1674
  }]
@@ -2285,6 +2498,7 @@ class GaRadioButtonComponent {
2285
2498
  tabindex = inject(new HostAttributeToken('tabindex'), {
2286
2499
  optional: true,
2287
2500
  });
2501
+ implicitNgControlState = injectNgControlState();
2288
2502
  _uniqueId = `ga-radio-button-${++nextUniqueId$3}`;
2289
2503
  /** The value attribute of the native input element */
2290
2504
  value = input(null);
@@ -2318,6 +2532,12 @@ class GaRadioButtonComponent {
2318
2532
  id = computed(() => this.inputId() ?? this._uniqueId);
2319
2533
  name = computed(() => this.radioGroup?.name() ?? this.inputName() ?? this._uniqueId);
2320
2534
  disabled = computed(() => this.radioGroup?.disabledModel() || this.inputDisabled());
2535
+ /** @ignore */
2536
+ invalid = computed(() => {
2537
+ return this.ariaInvalid()
2538
+ ? this.ariaInvalid() === 'true'
2539
+ : this.implicitNgControlState.inError();
2540
+ });
2321
2541
  checked = computed(() => this.radioGroup?.valueModel() === this.value() || this.inputChecked());
2322
2542
  onInputChange(event) {
2323
2543
  // We always have to stop propagation on the change event.
@@ -2334,13 +2554,13 @@ class GaRadioButtonComponent {
2334
2554
  this.radioGroup?.onBlur();
2335
2555
  }
2336
2556
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaRadioButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2337
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.0.4", type: GaRadioButtonComponent, isStandalone: true, selector: "ga-radio-button", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, inputId: { classPropertyName: "inputId", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, inputName: { classPropertyName: "inputName", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, inputChecked: { classPropertyName: "inputChecked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, inputDisabled: { classPropertyName: "inputDisabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "aria-labelledby", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedby: { classPropertyName: "ariaDescribedby", publicName: "aria-describedby", isSignal: true, isRequired: false, transformFunction: null }, ariaInvalid: { classPropertyName: "ariaInvalid", publicName: "aria-invalid", isSignal: true, isRequired: false, transformFunction: null }, ariaErrormessage: { classPropertyName: "ariaErrormessage", publicName: "aria-errormessage", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { change: "change" }, host: { properties: { "class.ga-radio-button--invalid": "ariaInvalid()", "attr.id": "null", "attr.tabindex": "null", "attr.aria-label": "null", "attr.aria-labelledby": "null", "attr.aria-describedby": "null" }, classAttribute: "ga-radio-button" }, ngImport: i0, template: "<input\n type=\"radio\"\n class=\"ga-radio-button__native\"\n [attr.id]=\"id()\"\n [name]=\"name()\"\n [checked]=\"checked()\"\n [disabled]=\"disabled()\"\n [attr.tabindex]=\"tabindex\"\n [attr.value]=\"value()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledby()\"\n [attr.aria-describedby]=\"ariaDescribedby()\"\n [attr.aria-invalid]=\"ariaInvalid()\"\n [attr.aria-errormessage]=\"ariaErrormessage()\"\n (change)=\"onInputChange($event)\"\n (blur)=\"onBlur()\"\n/>\n\n<div class=\"ga-radio-button__marker\"></div>\n<label class=\"ga-radio-button__label\" [attr.for]=\"id()\"\n ><ng-content></ng-content\n></label>\n", changeDetection: i0.ChangeDetectionStrategy.OnPush });
2557
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.0.4", type: GaRadioButtonComponent, isStandalone: true, selector: "ga-radio-button", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, inputId: { classPropertyName: "inputId", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, inputName: { classPropertyName: "inputName", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, inputChecked: { classPropertyName: "inputChecked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, inputDisabled: { classPropertyName: "inputDisabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "aria-labelledby", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedby: { classPropertyName: "ariaDescribedby", publicName: "aria-describedby", isSignal: true, isRequired: false, transformFunction: null }, ariaInvalid: { classPropertyName: "ariaInvalid", publicName: "aria-invalid", isSignal: true, isRequired: false, transformFunction: null }, ariaErrormessage: { classPropertyName: "ariaErrormessage", publicName: "aria-errormessage", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { change: "change" }, host: { properties: { "class.ga-radio-button--invalid": "invalid()", "attr.id": "null", "attr.tabindex": "null", "attr.aria-label": "null", "attr.aria-labelledby": "null", "attr.aria-describedby": "null" }, classAttribute: "ga-radio-button" }, ngImport: i0, template: "<input\n type=\"radio\"\n class=\"ga-radio-button__native\"\n [attr.id]=\"id()\"\n [name]=\"name()\"\n [checked]=\"checked()\"\n [disabled]=\"disabled()\"\n [attr.tabindex]=\"tabindex\"\n [attr.value]=\"value()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledby()\"\n [attr.aria-describedby]=\"ariaDescribedby()\"\n [attr.aria-invalid]=\"ariaInvalid()\"\n [attr.aria-errormessage]=\"ariaErrormessage()\"\n (change)=\"onInputChange($event)\"\n (blur)=\"onBlur()\"\n/>\n\n<div class=\"ga-radio-button__marker\"></div>\n<label class=\"ga-radio-button__label\" [attr.for]=\"id()\"\n ><ng-content></ng-content\n></label>\n", changeDetection: i0.ChangeDetectionStrategy.OnPush });
2338
2558
  }
2339
2559
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaRadioButtonComponent, decorators: [{
2340
2560
  type: Component,
2341
2561
  args: [{ selector: 'ga-radio-button', changeDetection: ChangeDetectionStrategy.OnPush, host: {
2342
2562
  class: 'ga-radio-button',
2343
- '[class.ga-radio-button--invalid]': 'ariaInvalid()',
2563
+ '[class.ga-radio-button--invalid]': 'invalid()',
2344
2564
  '[attr.id]': 'null',
2345
2565
  '[attr.tabindex]': 'null',
2346
2566
  '[attr.aria-label]': 'null',
@@ -2501,7 +2721,6 @@ let nextUniqueId$2 = 0;
2501
2721
  class GaSelectComponent {
2502
2722
  _uniqueId = `ga-select-${++nextUniqueId$2}`;
2503
2723
  icons = { CircleX };
2504
- focusedTriggerElement = null;
2505
2724
  _onTouched;
2506
2725
  _onModelChanged;
2507
2726
  positions = [
@@ -2536,11 +2755,15 @@ class GaSelectComponent {
2536
2755
  ];
2537
2756
  injector = inject(Injector);
2538
2757
  elementRef = inject((ElementRef));
2758
+ formFieldConnector = inject(GaFormFieldConnector, {
2759
+ optional: true,
2760
+ });
2539
2761
  i18n = inject(GaSelectI18n);
2540
2762
  overlayOrigin = inject(CdkOverlayOrigin);
2541
2763
  repositionScrollStrategy = createRepositionScrollStrategy(this.injector);
2542
- implicitInvalid = signal(false);
2764
+ implicitNgControlState = injectNgControlState();
2543
2765
  _isOpen = signal(false);
2766
+ shouldRecoverFocus = false;
2544
2767
  value = model(null);
2545
2768
  placeholder = input('');
2546
2769
  disabledInput = input(false, {
@@ -2599,14 +2822,8 @@ class GaSelectComponent {
2599
2822
  return this.value() !== null || this.canSelectNullable();
2600
2823
  });
2601
2824
  invalid = computed(() => {
2602
- return this.invalidInput() ?? this.implicitInvalid();
2603
- });
2604
- _formControlId = computed(() => {
2605
- // NOTE: The custom select cannot be connected to the label through `for` and `id` attributes,
2606
- // therefore `null` is returned here.
2607
- return null;
2825
+ return this.invalidInput() ?? this.implicitNgControlState.inError();
2608
2826
  });
2609
- _formControlDisabled = computed(() => this.disabled());
2610
2827
  constructor() {
2611
2828
  effect(() => {
2612
2829
  // if the select became disabled while open, close it
@@ -2614,6 +2831,10 @@ class GaSelectComponent {
2614
2831
  this.close();
2615
2832
  }
2616
2833
  });
2834
+ const formFieldConnector = this.formFieldConnector;
2835
+ if (formFieldConnector) {
2836
+ effect(() => formFieldConnector.controlDisabled.set(this.disabled()));
2837
+ }
2617
2838
  }
2618
2839
  ngAfterContentInit() {
2619
2840
  effect(() => {
@@ -2635,15 +2856,6 @@ class GaSelectComponent {
2635
2856
  this.autoClose();
2636
2857
  });
2637
2858
  }
2638
- ngDoCheck() {
2639
- const implicitNgControl = this.injector.get(NgControl, null, {
2640
- self: true,
2641
- });
2642
- // we can rely on computed because `ivalid` of NgControl is not a signal, yet
2643
- if (implicitNgControl) {
2644
- this.implicitInvalid.set(!!implicitNgControl.invalid && !!implicitNgControl.dirty);
2645
- }
2646
- }
2647
2859
  writeValue(value) {
2648
2860
  this.value.set(value);
2649
2861
  }
@@ -2679,6 +2891,7 @@ class GaSelectComponent {
2679
2891
  autoClose() {
2680
2892
  // close that was initiated by clicking the option
2681
2893
  if (!this.multiple()) {
2894
+ this.shouldRecoverFocus = true;
2682
2895
  this.close();
2683
2896
  }
2684
2897
  }
@@ -2707,10 +2920,19 @@ class GaSelectComponent {
2707
2920
  this.syncValue();
2708
2921
  }
2709
2922
  }
2923
+ onOverlayKeydown(event) {
2924
+ if (event.code === 'Escape') {
2925
+ this.shouldRecoverFocus = true;
2926
+ }
2927
+ }
2710
2928
  clearValue() {
2711
2929
  if (!this.clearable() || !this.searchable()) {
2712
2930
  return;
2713
2931
  }
2932
+ if (this.elementRef.nativeElement !== document.activeElement &&
2933
+ this.inputSearch()?.nativeElement !== document.activeElement) {
2934
+ this._onTouched?.();
2935
+ }
2714
2936
  this.value.set(null);
2715
2937
  this._onModelChanged?.(null);
2716
2938
  this.autoClose();
@@ -2737,15 +2959,16 @@ class GaSelectComponent {
2737
2959
  event.stopPropagation();
2738
2960
  break;
2739
2961
  case 'Backspace':
2740
- this.clearValue();
2741
- event.preventDefault();
2962
+ if (this.textValue() === '') {
2963
+ this.clearValue();
2964
+ }
2742
2965
  event.stopPropagation();
2743
2966
  break;
2744
2967
  }
2745
2968
  }
2746
2969
  onOverlayAttach() {
2970
+ this.shouldRecoverFocus = false;
2747
2971
  this._isOpen.set(true);
2748
- this.focusedTriggerElement = document.activeElement;
2749
2972
  if (this.searchable()) {
2750
2973
  this.inputSearch().nativeElement.focus();
2751
2974
  }
@@ -2756,10 +2979,8 @@ class GaSelectComponent {
2756
2979
  }
2757
2980
  onOverlayDetach() {
2758
2981
  this._isOpen.set(false);
2759
- if (this.inputSearch()?.nativeElement !== this.focusedTriggerElement) {
2760
- this.focusedTriggerElement?.focus();
2761
- }
2762
- else if (this.searchable()) {
2982
+ if (this.inputSearch()?.nativeElement === document.activeElement ||
2983
+ this.shouldRecoverFocus) {
2763
2984
  this.elementRef.nativeElement.focus();
2764
2985
  }
2765
2986
  this.textValue.set('');
@@ -2805,11 +3026,7 @@ class GaSelectComponent {
2805
3026
  useExisting: forwardRef(() => GaSelectComponent),
2806
3027
  multi: true,
2807
3028
  },
2808
- {
2809
- provide: GA_FORM_CONTROL,
2810
- useExisting: forwardRef(() => GaSelectComponent),
2811
- },
2812
- ], queries: [{ propertyName: "gaOptions", predicate: GaOptionComponent, descendants: true, read: GaOptionComponent, isSignal: true }, { propertyName: "cdkListbox", first: true, predicate: CdkListbox, descendants: true, isSignal: true }, { propertyName: "customSelectValue", first: true, predicate: GaSelectValueComponent, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "inputSearch", first: true, predicate: ["inputSearch"], descendants: true, isSignal: true }, { propertyName: "content", first: true, predicate: ["ngContent"], descendants: true, read: ElementRef, isSignal: true }], hostDirectives: [{ directive: i1$5.CdkOverlayOrigin }, { directive: GaLabelledByFormFieldDirective, inputs: ["aria-labelledby", "aria-labelledby"] }], ngImport: i0, template: "@if (leftIcon()) {\n <ga-icon [icon]=\"leftIcon()!\" />\n}\n\n<div class=\"ga-select__main-area\">\n @if (hasValue() && (!textValue() || multiple())) {\n @if (customSelectValue()) {\n <div class=\"ga-select__value\">\n <ng-content select=\"ga-select-value\" />\n </div>\n } @else {\n <ga-select-default-value />\n }\n } @else if (!searchable()) {\n <div class=\"ga-select__placeholder\">\n {{ placeholder() }}\n </div>\n }\n\n @if (searchable()) {\n <input\n #inputSearch\n type=\"text\"\n class=\"ga-select__input\"\n aria-autocomplete=\"list\"\n [value]=\"textValue()\"\n (input)=\"open(); textValue.set(inputSearch.value)\"\n (click)=\"open(); $event.stopPropagation()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-controls]=\"cdkListbox().id\"\n [attr.aria-activedescendant]=\"activeDescendantId()\"\n [placeholder]=\"hasValue() ? '' : placeholder()\"\n (keydown)=\"onInputKeyDown($event)\"\n tabindex=\"-1\"\n />\n }\n</div>\n\n<div class=\"ga-select__suffix\">\n @if (clearable() && hasValue()) {\n <button\n type=\"button\"\n tabindex=\"-1\"\n (click)=\"clearValue(); $event.stopPropagation()\"\n [attr.aria-label]=\"clearableLabel() ?? i18n.clearLabel\"\n >\n <ga-icon [icon]=\"icons.CircleX\" size=\"16\" />\n </button>\n }\n\n <ga-icon [icon]=\"menuStatusIcon()\" class=\"ga-select__action-icon\" />\n</div>\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayLockPosition\n [cdkConnectedOverlayOrigin]=\"overlayOrigin\"\n [cdkConnectedOverlayOpen]=\"isOpen()\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayScrollStrategy]=\"repositionScrollStrategy\"\n (overlayOutsideClick)=\"close()\"\n (attach)=\"onOverlayAttach()\"\n (detach)=\"onOverlayDetach()\"\n>\n <ng-content select=\"ga-select-dropdown\" />\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: GaIconModule }, { kind: "component", type: GaIconComponent, selector: "ga-icon", inputs: ["icon", "size", "color", "strokeWidth"] }, { kind: "ngmodule", type: GaButtonModule }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i1$5.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "component", type: GaSelectDefaultValueComponent, selector: "ga-select-default-value" }] });
3029
+ ], queries: [{ propertyName: "gaOptions", predicate: GaOptionComponent, descendants: true, read: GaOptionComponent, isSignal: true }, { propertyName: "cdkListbox", first: true, predicate: CdkListbox, descendants: true, isSignal: true }, { propertyName: "customSelectValue", first: true, predicate: GaSelectValueComponent, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "inputSearch", first: true, predicate: ["inputSearch"], descendants: true, isSignal: true }, { propertyName: "content", first: true, predicate: ["ngContent"], descendants: true, read: ElementRef, isSignal: true }], hostDirectives: [{ directive: i1$5.CdkOverlayOrigin }, { directive: GaLabelledByFormFieldDirective, inputs: ["aria-labelledby", "aria-labelledby"] }], ngImport: i0, template: "@if (leftIcon()) {\n <ga-icon [icon]=\"leftIcon()!\" />\n}\n\n<div class=\"ga-select__main-area\">\n @if (hasValue() && (!textValue() || multiple())) {\n @if (customSelectValue()) {\n <div class=\"ga-select__value\">\n <ng-content select=\"ga-select-value\" />\n </div>\n } @else {\n <ga-select-default-value />\n }\n } @else if (!searchable()) {\n <div class=\"ga-select__placeholder\">\n {{ placeholder() }}\n </div>\n }\n\n @if (searchable()) {\n <input\n #inputSearch\n type=\"text\"\n class=\"ga-select__input\"\n aria-autocomplete=\"list\"\n [value]=\"textValue()\"\n (input)=\"open(); textValue.set(inputSearch.value)\"\n (click)=\"open(); $event.stopPropagation()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-controls]=\"cdkListbox().id\"\n [attr.aria-activedescendant]=\"activeDescendantId()\"\n [placeholder]=\"hasValue() ? '' : placeholder()\"\n (keydown)=\"onInputKeyDown($event)\"\n tabindex=\"-1\"\n [disabled]=\"disabled()\"\n />\n }\n</div>\n\n<div class=\"ga-select__suffix\">\n @if (clearable() && hasValue()) {\n <button\n type=\"button\"\n tabindex=\"-1\"\n (click)=\"clearValue(); $event.stopPropagation()\"\n [attr.aria-label]=\"clearableLabel() ?? i18n.clearLabel\"\n style=\"font-size: 0\"\n >\n <ga-icon [icon]=\"icons.CircleX\" size=\"16\" />\n </button>\n }\n\n <ga-icon [icon]=\"menuStatusIcon()\" class=\"ga-select__action-icon\" />\n</div>\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayLockPosition\n [cdkConnectedOverlayOrigin]=\"overlayOrigin\"\n [cdkConnectedOverlayOpen]=\"isOpen()\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayScrollStrategy]=\"repositionScrollStrategy\"\n (overlayOutsideClick)=\"close()\"\n (attach)=\"onOverlayAttach()\"\n (detach)=\"onOverlayDetach()\"\n (overlayKeydown)=\"onOverlayKeydown($event)\"\n>\n <ng-content select=\"ga-select-dropdown\" />\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: GaIconModule }, { kind: "component", type: GaIconComponent, selector: "ga-icon", inputs: ["icon", "size", "color", "strokeWidth"] }, { kind: "ngmodule", type: GaButtonModule }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i1$5.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "component", type: GaSelectDefaultValueComponent, selector: "ga-select-default-value" }] });
2813
3030
  }
2814
3031
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaSelectComponent, decorators: [{
2815
3032
  type: Component,
@@ -2830,10 +3047,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImpor
2830
3047
  useExisting: forwardRef(() => GaSelectComponent),
2831
3048
  multi: true,
2832
3049
  },
2833
- {
2834
- provide: GA_FORM_CONTROL,
2835
- useExisting: forwardRef(() => GaSelectComponent),
2836
- },
2837
3050
  ], host: {
2838
3051
  role: 'combobox',
2839
3052
  '[attr.id]': 'id()',
@@ -2856,7 +3069,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImpor
2856
3069
  '(keydown.space)': 'open(); $event.preventDefault()',
2857
3070
  '(keydown.enter)': 'open(); $event.preventDefault()',
2858
3071
  '(keydown.backspace)': 'clearValue(); $event.preventDefault()',
2859
- }, template: "@if (leftIcon()) {\n <ga-icon [icon]=\"leftIcon()!\" />\n}\n\n<div class=\"ga-select__main-area\">\n @if (hasValue() && (!textValue() || multiple())) {\n @if (customSelectValue()) {\n <div class=\"ga-select__value\">\n <ng-content select=\"ga-select-value\" />\n </div>\n } @else {\n <ga-select-default-value />\n }\n } @else if (!searchable()) {\n <div class=\"ga-select__placeholder\">\n {{ placeholder() }}\n </div>\n }\n\n @if (searchable()) {\n <input\n #inputSearch\n type=\"text\"\n class=\"ga-select__input\"\n aria-autocomplete=\"list\"\n [value]=\"textValue()\"\n (input)=\"open(); textValue.set(inputSearch.value)\"\n (click)=\"open(); $event.stopPropagation()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-controls]=\"cdkListbox().id\"\n [attr.aria-activedescendant]=\"activeDescendantId()\"\n [placeholder]=\"hasValue() ? '' : placeholder()\"\n (keydown)=\"onInputKeyDown($event)\"\n tabindex=\"-1\"\n />\n }\n</div>\n\n<div class=\"ga-select__suffix\">\n @if (clearable() && hasValue()) {\n <button\n type=\"button\"\n tabindex=\"-1\"\n (click)=\"clearValue(); $event.stopPropagation()\"\n [attr.aria-label]=\"clearableLabel() ?? i18n.clearLabel\"\n >\n <ga-icon [icon]=\"icons.CircleX\" size=\"16\" />\n </button>\n }\n\n <ga-icon [icon]=\"menuStatusIcon()\" class=\"ga-select__action-icon\" />\n</div>\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayLockPosition\n [cdkConnectedOverlayOrigin]=\"overlayOrigin\"\n [cdkConnectedOverlayOpen]=\"isOpen()\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayScrollStrategy]=\"repositionScrollStrategy\"\n (overlayOutsideClick)=\"close()\"\n (attach)=\"onOverlayAttach()\"\n (detach)=\"onOverlayDetach()\"\n>\n <ng-content select=\"ga-select-dropdown\" />\n</ng-template>\n" }]
3072
+ }, template: "@if (leftIcon()) {\n <ga-icon [icon]=\"leftIcon()!\" />\n}\n\n<div class=\"ga-select__main-area\">\n @if (hasValue() && (!textValue() || multiple())) {\n @if (customSelectValue()) {\n <div class=\"ga-select__value\">\n <ng-content select=\"ga-select-value\" />\n </div>\n } @else {\n <ga-select-default-value />\n }\n } @else if (!searchable()) {\n <div class=\"ga-select__placeholder\">\n {{ placeholder() }}\n </div>\n }\n\n @if (searchable()) {\n <input\n #inputSearch\n type=\"text\"\n class=\"ga-select__input\"\n aria-autocomplete=\"list\"\n [value]=\"textValue()\"\n (input)=\"open(); textValue.set(inputSearch.value)\"\n (click)=\"open(); $event.stopPropagation()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-controls]=\"cdkListbox().id\"\n [attr.aria-activedescendant]=\"activeDescendantId()\"\n [placeholder]=\"hasValue() ? '' : placeholder()\"\n (keydown)=\"onInputKeyDown($event)\"\n tabindex=\"-1\"\n [disabled]=\"disabled()\"\n />\n }\n</div>\n\n<div class=\"ga-select__suffix\">\n @if (clearable() && hasValue()) {\n <button\n type=\"button\"\n tabindex=\"-1\"\n (click)=\"clearValue(); $event.stopPropagation()\"\n [attr.aria-label]=\"clearableLabel() ?? i18n.clearLabel\"\n style=\"font-size: 0\"\n >\n <ga-icon [icon]=\"icons.CircleX\" size=\"16\" />\n </button>\n }\n\n <ga-icon [icon]=\"menuStatusIcon()\" class=\"ga-select__action-icon\" />\n</div>\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayLockPosition\n [cdkConnectedOverlayOrigin]=\"overlayOrigin\"\n [cdkConnectedOverlayOpen]=\"isOpen()\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayScrollStrategy]=\"repositionScrollStrategy\"\n (overlayOutsideClick)=\"close()\"\n (attach)=\"onOverlayAttach()\"\n (detach)=\"onOverlayDetach()\"\n (overlayKeydown)=\"onOverlayKeydown($event)\"\n>\n <ng-content select=\"ga-select-dropdown\" />\n</ng-template>\n" }]
2860
3073
  }], ctorParameters: () => [] });
2861
3074
 
2862
3075
  class GaOptgroupComponent {
@@ -2996,8 +3209,9 @@ let nextUniqueId$1 = 0;
2996
3209
  class GaSwitchComponent {
2997
3210
  icons = { Check };
2998
3211
  /** @ignore */
3212
+ implicitNgControlState = injectNgControlState();
3213
+ /** @ignore */
2999
3214
  _uniqueId = `ga-switch-${++nextUniqueId$1}`;
3000
- injector = inject(Injector);
3001
3215
  /** @ignore */
3002
3216
  tabindex = input(0, {
3003
3217
  alias: 'tabindex',
@@ -3006,19 +3220,13 @@ class GaSwitchComponent {
3006
3220
  _onTouched;
3007
3221
  /** @ignore */
3008
3222
  _onModelChanged;
3009
- /** @ignore */
3010
- _invalidNgModel = signal(false);
3011
- _ngModelName = signal(null);
3012
3223
  checked = input(false, {
3013
3224
  transform: booleanAttribute,
3014
3225
  });
3015
3226
  disabled = input(false, {
3016
3227
  transform: booleanAttribute,
3017
3228
  });
3018
- ariaInvalid = input(false, {
3019
- transform: booleanAttribute,
3020
- alias: 'aria-invalid',
3021
- });
3229
+ ariaInvalid = input(null, { alias: 'aria-invalid' });
3022
3230
  label = input('');
3023
3231
  ariaLabel = input(null, { alias: 'aria-label' });
3024
3232
  ariaLabelledby = input(null, {
@@ -3039,23 +3247,14 @@ class GaSwitchComponent {
3039
3247
  inputId = computed(() => this.id() ?? this._uniqueId);
3040
3248
  /** @ignore */
3041
3249
  name = computed(() => {
3042
- return this.nameInput() ?? this._ngModelName() ?? this._uniqueId;
3250
+ return (this.nameInput() ?? this.implicitNgControlState.name() ?? this._uniqueId);
3043
3251
  });
3044
3252
  /** @ignore */
3045
3253
  invalidComputed = computed(() => {
3046
- return this.ariaInvalid() || this._invalidNgModel();
3254
+ return this.ariaInvalid()
3255
+ ? this.ariaInvalid() === 'true'
3256
+ : this.implicitNgControlState.inError();
3047
3257
  });
3048
- ngDoCheck() {
3049
- const implicitNgControl = this.injector.get(NgControl, null, {
3050
- self: true,
3051
- });
3052
- if (implicitNgControl) {
3053
- this._invalidNgModel.set(!!implicitNgControl.invalid && !!implicitNgControl.dirty);
3054
- if (implicitNgControl.name) {
3055
- this._ngModelName.set(implicitNgControl.name);
3056
- }
3057
- }
3058
- }
3059
3258
  /** @ignore */
3060
3259
  onInputChange(event) {
3061
3260
  const target = event.target;
@@ -3206,26 +3405,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImpor
3206
3405
 
3207
3406
  let nextUniqueId = 0;
3208
3407
  class GaTextAreaDirective {
3209
- id = input(undefined);
3210
- disabled = input(false, { transform: booleanAttribute });
3211
- invalid = input(undefined, { transform: booleanAttribute });
3212
- _formControlId = computed(() => this.uniqueId());
3213
- _formControlDisabled = computed(() => this.disabledModel());
3214
- uniqueId = computed(() => this.id() ?? this.generatedUniqueId);
3215
- invalidInput = computed(() => this.invalid() ?? this.implicitInvalid());
3216
- generatedUniqueId = `ga-text-area-${++nextUniqueId}`;
3217
- injector = inject(Injector);
3218
- implicitInvalid = signal(false);
3219
- disabledModel = linkedSignal(() => this.disabled());
3220
- ngDoCheck() {
3221
- const ngControl = this.injector.get(NgControl, null, { self: true });
3222
- if (ngControl) {
3223
- this.implicitInvalid.set(!!ngControl.invalid && !!ngControl.dirty);
3224
- this.disabledModel.set(!!ngControl.disabled);
3408
+ implicitNgControlState = injectNgControlState();
3409
+ formFieldConnector = inject(GaFormFieldConnector, {
3410
+ optional: true,
3411
+ });
3412
+ uniqueId = `ga-text-area-${++nextUniqueId}`;
3413
+ idInput = input(undefined, { alias: 'id' });
3414
+ disabledInput = input(false, {
3415
+ alias: 'disabled',
3416
+ transform: booleanAttribute,
3417
+ });
3418
+ invalidInput = input(undefined, {
3419
+ alias: 'invalid',
3420
+ transform: booleanAttribute,
3421
+ });
3422
+ disabled = computed(() => this.disabledInput() ?? this.implicitNgControlState.disabled());
3423
+ invalid = computed(() => this.invalidInput() ?? this.implicitNgControlState.inError());
3424
+ id = computed(() => this.idInput() ?? this.uniqueId);
3425
+ constructor() {
3426
+ const formFieldConnector = this.formFieldConnector;
3427
+ if (formFieldConnector) {
3428
+ effect(() => formFieldConnector.controlDisabled.set(this.disabled()));
3429
+ effect(() => formFieldConnector.controlId.set(this.id()));
3225
3430
  }
3226
3431
  }
3227
3432
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaTextAreaDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
3228
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.0.4", type: GaTextAreaDirective, isStandalone: true, selector: "[gaTextArea]", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.ga-text-area--invalid": "invalidInput()", "attr.id": "uniqueId()" }, classAttribute: "ga-text-area" }, ngImport: i0 });
3433
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.0.4", type: GaTextAreaDirective, isStandalone: true, selector: "[gaTextArea]", inputs: { idInput: { classPropertyName: "idInput", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, invalidInput: { classPropertyName: "invalidInput", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.ga-text-area--invalid": "invalid()", "attr.id": "id()" }, classAttribute: "ga-text-area" }, ngImport: i0 });
3229
3434
  }
3230
3435
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaTextAreaDirective, decorators: [{
3231
3436
  type: Directive,
@@ -3233,11 +3438,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImpor
3233
3438
  selector: '[gaTextArea]',
3234
3439
  host: {
3235
3440
  class: 'ga-text-area',
3236
- '[class.ga-text-area--invalid]': 'invalidInput()',
3237
- '[attr.id]': 'uniqueId()',
3441
+ '[class.ga-text-area--invalid]': 'invalid()',
3442
+ '[attr.id]': 'id()',
3238
3443
  },
3239
3444
  }]
3240
- }] });
3445
+ }], ctorParameters: () => [] });
3241
3446
 
3242
3447
  class GaTextAreaModule {
3243
3448
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaTextAreaModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
@@ -3260,5 +3465,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImpor
3260
3465
  * Generated bundle index. Do not edit.
3261
3466
  */
3262
3467
 
3263
- export { CHECKBOX_CONTROL_VALUE_ACCESSOR, DEFAULT_MODAL_OPTIONS, GA_ALERT_I18N_FACTORY, GA_BASE_FONT_SIZE, GA_BUTTON_I18N_FACTORY, GA_CHECKBOX_REQUIRED_VALIDATOR, GA_FORM_CONTROL, GA_ICON_DEFAULT_SIZE, GA_MODAL_DATA, GA_MODAL_I18N_FACTORY, GA_SELECT_I18N_FACTORY, GA_SELECT_REQUIRED_VALIDATOR, GA_TOOLTIP_DEFAULT_OFFSET, GaAlertComponent, GaAlertI18n, GaAlertI18nDefault, GaAlertModule, GaAlertTitleActionsComponent, GaAlertTitleComponent, GaBadgeComponent, GaBadgeModule, GaButtonDirective, GaButtonI18n, GaButtonI18nDefault, GaButtonModule, GaCardComponent, GaCardModule, GaCheckboxComponent, GaCheckboxModule, GaCheckboxRequiredValidator, GaFieldInfoComponent, GaFieldLabelComponent, GaFormControlDirective, GaFormFieldComponent, GaFormFieldModule, GaIconButtonDirective, GaIconComponent, GaIconModule, GaInputComponent, GaInputDirective, GaInputModule, GaLabelledByFormFieldDirective, GaLinkDirective, GaLinkModule, GaMenuComponent, GaMenuItemComponent, GaMenuModule, GaMenuSeparatorComponent, GaMenuTitleComponent, GaMenuTriggerDirective, GaMenuTriggerIconComponent, GaModalActionsComponent, GaModalCloseDirective, GaModalComponent, GaModalContentComponent, GaModalDescriptionComponent, GaModalDescriptionDirective, GaModalHeaderComponent, GaModalI18n, GaModalI18nDefault, GaModalLabelDirective, GaModalModule, GaModalOptions, GaModalRef, GaModalService, GaModalTitleDirective, GaOptgroupComponent, GaOptionComponent, GaRadioButtonComponent, GaRadioGroupComponent, GaRadioModule, GaSegmentedControlButtonDirective, GaSegmentedControlComponent, GaSegmentedControlIconButtonComponent, GaSegmentedControlModule, GaSegmentedControlTextButtonComponent, GaSelectComponent, GaSelectDropdownComponent, GaSelectDropdownSpinnerComponent, GaSelectI18n, GaSelectI18nDefault, GaSelectModule, GaSelectRequiredValidator, GaSelectValueComponent, GaSpinnerComponent, GaSpinnerModule, GaSwitchComponent, GaSwitchModule, GaTextAreaDirective, GaTextAreaModule, GaTooltipComponent, GaTooltipDirective, GaTooltipModule, RADIO_CONTROL_VALUE_ACCESSOR, SWITCH_CONTROL_VALUE_ACCESSOR, provideGaAlertI18n, provideGaBaseFontSize, provideGaButtonI18n, provideGaModalI18n, provideGaModalOptions, provideGaSelectI18n };
3468
+ export { CHECKBOX_CONTROL_VALUE_ACCESSOR, DEFAULT_MODAL_OPTIONS, GA_ALERT_I18N_FACTORY, GA_BASE_FONT_SIZE, GA_BUTTON_I18N_FACTORY, GA_CHECKBOX_REQUIRED_VALIDATOR, GA_FORM_CONTROL_ADAPTER, GA_ICON_DEFAULT_SIZE, GA_MODAL_DATA, GA_MODAL_I18N_FACTORY, GA_SELECT_I18N_FACTORY, GA_SELECT_REQUIRED_VALIDATOR, GA_TOOLTIP_DEFAULT_OFFSET, GaAlertComponent, GaAlertI18n, GaAlertI18nDefault, GaAlertModule, GaAlertTitleActionsComponent, GaAlertTitleComponent, GaBadgeComponent, GaBadgeModule, GaButtonDirective, GaButtonI18n, GaButtonI18nDefault, GaButtonModule, GaCardComponent, GaCardModule, GaCheckboxComponent, GaCheckboxModule, GaCheckboxRequiredValidator, GaFieldErrorDirective, GaFieldInfoComponent, GaFieldLabelComponent, GaFormControlDirective, GaFormControlErrorsDirective, GaFormFieldComponent, GaFormFieldConnector, GaFormFieldModule, GaIconButtonDirective, GaIconComponent, GaIconModule, GaInputComponent, GaInputDirective, GaInputModule, GaLabelledByFormFieldDirective, GaLinkDirective, GaLinkModule, GaMenuComponent, GaMenuItemComponent, GaMenuModule, GaMenuSeparatorComponent, GaMenuTitleComponent, GaMenuTriggerDirective, GaMenuTriggerIconComponent, GaModalActionsComponent, GaModalCloseDirective, GaModalComponent, GaModalContentComponent, GaModalDescriptionComponent, GaModalDescriptionDirective, GaModalHeaderComponent, GaModalI18n, GaModalI18nDefault, GaModalLabelDirective, GaModalModule, GaModalOptions, GaModalRef, GaModalService, GaModalTitleDirective, GaOptgroupComponent, GaOptionComponent, GaRadioButtonComponent, GaRadioGroupComponent, GaRadioModule, GaSegmentedControlButtonDirective, GaSegmentedControlComponent, GaSegmentedControlIconButtonComponent, GaSegmentedControlModule, GaSegmentedControlTextButtonComponent, GaSelectComponent, GaSelectDropdownComponent, GaSelectDropdownSpinnerComponent, GaSelectI18n, GaSelectI18nDefault, GaSelectModule, GaSelectRequiredValidator, GaSelectValueComponent, GaSpinnerComponent, GaSpinnerModule, GaSwitchComponent, GaSwitchModule, GaTextAreaDirective, GaTextAreaModule, GaTooltipComponent, GaTooltipDirective, GaTooltipModule, RADIO_CONTROL_VALUE_ACCESSOR, SWITCH_CONTROL_VALUE_ACCESSOR, injectNgControlState, provideGaAlertI18n, provideGaBaseFontSize, provideGaButtonI18n, provideGaModalI18n, provideGaModalOptions, provideGaSelectI18n };
3264
3469
  //# sourceMappingURL=vsn-ux-ngx-gaia.mjs.map