@vsn-ux/ngx-gaia 0.9.1 → 0.9.3

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,23 +1,23 @@
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, Directive, linkedSignal, signal, Injector, DestroyRef, effect, isSignal, forwardRef, model, HostListener, viewChild, TemplateRef, contentChildren, NgZone, HostBinding, Input, DOCUMENT, afterNextRender, Renderer2, afterEveryRender } 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, LOCALE_ID, model, Renderer2, Attribute, untracked, HostListener, viewChild, TemplateRef, contentChildren, NgZone, HostBinding, Input, DOCUMENT, afterNextRender, afterEveryRender } from '@angular/core';
3
3
  import * as i1 from 'lucide-angular';
4
- import { LucideAngularModule, X, CircleCheck, TriangleAlert, OctagonAlert, Info, Check, Minus, ChevronUp, ChevronDown, CircleX } from 'lucide-angular';
4
+ import { LucideAngularModule, X, CircleCheck, TriangleAlert, OctagonAlert, Info, Check, Minus, ChevronDown, ChevronUp, ChevronRight, ChevronLeft, CalendarDays, CircleX } from 'lucide-angular';
5
5
  import { NgForm, ControlContainer, NgControl, NG_VALUE_ACCESSOR, NG_VALIDATORS, CheckboxRequiredValidator, RequiredValidator } from '@angular/forms';
6
6
  import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
7
+ import * as i1$1 from '@angular/cdk/overlay';
8
+ import { CdkOverlayOrigin, createRepositionScrollStrategy, OverlayModule, Overlay, OverlayRef, CdkConnectedOverlay } from '@angular/cdk/overlay';
7
9
  import { NgTemplateOutlet } from '@angular/common';
8
- import * as i1$5 from '@angular/cdk/overlay';
9
- import { Overlay, createRepositionScrollStrategy, OverlayRef, CdkOverlayOrigin, OverlayModule } from '@angular/cdk/overlay';
10
10
  import { ComponentPortal } from '@angular/cdk/portal';
11
11
  import { Subject, takeUntil, map, merge, filter, Observable, isObservable } from 'rxjs';
12
12
  import { ESCAPE, hasModifierKey } from '@angular/cdk/keycodes';
13
- import * as i1$1 from '@angular/cdk/menu';
13
+ import * as i1$2 from '@angular/cdk/menu';
14
14
  import { CdkMenu, CdkMenuItem, CdkMenuTrigger, MENU_SCROLL_STRATEGY } from '@angular/cdk/menu';
15
15
  import { Router, ResolveStart } from '@angular/router';
16
- import * as i1$2 from '@angular/cdk/a11y';
16
+ import * as i1$3 from '@angular/cdk/a11y';
17
17
  import { CdkTrapFocus } from '@angular/cdk/a11y';
18
- import * as i1$3 from '@angular/cdk/scrolling';
18
+ import * as i1$4 from '@angular/cdk/scrolling';
19
19
  import { CdkScrollable } from '@angular/cdk/scrolling';
20
- import * as i1$4 from '@angular/cdk/listbox';
20
+ import * as i1$5 from '@angular/cdk/listbox';
21
21
  import { CdkOption, CdkListbox } from '@angular/cdk/listbox';
22
22
 
23
23
  /**
@@ -802,6 +802,1095 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImpor
802
802
  }]
803
803
  }] });
804
804
 
805
+ function isClass(value) {
806
+ return (typeof value === 'function' &&
807
+ value.prototype &&
808
+ value.prototype.constructor === value);
809
+ }
810
+
811
+ function GA_DATEPICKER_I18N_FACTORY() {
812
+ return new GaDatepickerI18nDefault();
813
+ }
814
+ class GaDatepickerI18n {
815
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerI18n, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
816
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerI18n, providedIn: 'root', useFactory: GA_DATEPICKER_I18N_FACTORY });
817
+ }
818
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerI18n, decorators: [{
819
+ type: Injectable,
820
+ args: [{
821
+ providedIn: 'root',
822
+ useFactory: GA_DATEPICKER_I18N_FACTORY,
823
+ }]
824
+ }] });
825
+ class GaDatepickerI18nDefault extends GaDatepickerI18n {
826
+ localeId = inject(LOCALE_ID);
827
+ selectMonthLabel = 'Select month';
828
+ selectYearLabel = 'Select year';
829
+ previousLabel = 'Previous';
830
+ nextLabel = 'Next';
831
+ openCalendarLabel = 'Open calendar';
832
+ todayButtonLabel = 'Today';
833
+ monthNames;
834
+ monthNamesShort;
835
+ weekDays;
836
+ constructor() {
837
+ super();
838
+ // Generate month names using Intl API
839
+ const monthFormatter = new Intl.DateTimeFormat(this.localeId, {
840
+ month: 'long',
841
+ });
842
+ const monthShortFormatter = new Intl.DateTimeFormat(this.localeId, {
843
+ month: 'short',
844
+ });
845
+ this.monthNames = Array.from({ length: 12 }, (_, i) => {
846
+ const date = new Date(2024, i, 1);
847
+ return monthFormatter.format(date);
848
+ });
849
+ this.monthNamesShort = Array.from({ length: 12 }, (_, i) => {
850
+ const date = new Date(2024, i, 1);
851
+ return monthShortFormatter.format(date);
852
+ });
853
+ // Generate weekday names using Intl API (starting from Monday)
854
+ const weekdayFormatter = new Intl.DateTimeFormat(this.localeId, {
855
+ weekday: 'short',
856
+ });
857
+ const weekDayDates = Array.from({ length: 7 }, (_, i) => {
858
+ // January 2024 starts on Monday, so we can use dates 1-7
859
+ return new Date(2024, 0, i + 1);
860
+ });
861
+ this.weekDays = weekDayDates.map((date) => {
862
+ return weekdayFormatter.format(date);
863
+ });
864
+ }
865
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerI18nDefault, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
866
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerI18nDefault, providedIn: 'root' });
867
+ }
868
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerI18nDefault, decorators: [{
869
+ type: Injectable,
870
+ args: [{ providedIn: 'root' }]
871
+ }], ctorParameters: () => [] });
872
+ function provideGaDatepickerI18n(value) {
873
+ if (isClass(value)) {
874
+ return makeEnvironmentProviders([
875
+ { provide: GaDatepickerI18n, useClass: value },
876
+ ]);
877
+ }
878
+ return makeEnvironmentProviders([
879
+ {
880
+ provide: GaDatepickerI18n,
881
+ useFactory: () => {
882
+ const defaultI18n = inject(GaDatepickerI18nDefault);
883
+ const i18n = {
884
+ monthNames: defaultI18n.monthNames,
885
+ monthNamesShort: defaultI18n.monthNamesShort,
886
+ weekDays: defaultI18n.weekDays,
887
+ ...(typeof value === 'function' ? value() : value),
888
+ };
889
+ return i18n;
890
+ },
891
+ },
892
+ ]);
893
+ }
894
+
895
+ function GA_DATEPICKER_VALUE_ADAPTER_FACTORY() {
896
+ return new GaDatepickerStructValueAdapter();
897
+ }
898
+ class GaDatepickerValueAdapter {
899
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerValueAdapter, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
900
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerValueAdapter, providedIn: 'root', useFactory: GA_DATEPICKER_VALUE_ADAPTER_FACTORY });
901
+ }
902
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerValueAdapter, decorators: [{
903
+ type: Injectable,
904
+ args: [{
905
+ providedIn: 'root',
906
+ useFactory: GA_DATEPICKER_VALUE_ADAPTER_FACTORY,
907
+ }]
908
+ }] });
909
+ class GaDatepickerStructValueAdapter extends GaDatepickerValueAdapter {
910
+ /**
911
+ * Checks if a value is a valid GaDatepickerStruct
912
+ */
913
+ isStruct(value) {
914
+ return (value &&
915
+ typeof value === 'object' &&
916
+ typeof value.year === 'number' &&
917
+ typeof value.month === 'number' &&
918
+ typeof value.day === 'number');
919
+ }
920
+ /**
921
+ * Handles GaDatepickerStruct natively - pass through as-is
922
+ */
923
+ toStruct(value) {
924
+ if (!value)
925
+ return null;
926
+ if (this.isStruct(value))
927
+ return value;
928
+ return null; // Invalid input
929
+ }
930
+ /**
931
+ * Returns struct as-is (no conversion needed)
932
+ */
933
+ fromStruct(struct) {
934
+ return struct;
935
+ }
936
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerStructValueAdapter, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
937
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerStructValueAdapter });
938
+ }
939
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerStructValueAdapter, decorators: [{
940
+ type: Injectable
941
+ }] });
942
+ function provideGaDatepickerValueAdapter(value) {
943
+ return { provide: GaDatepickerValueAdapter, useClass: value };
944
+ }
945
+ /**
946
+ * Compares two structs for equality
947
+ */
948
+ function compareStructs(structA, structB) {
949
+ if (!structA && !structB)
950
+ return 0;
951
+ if (!structA)
952
+ return -1;
953
+ if (!structB)
954
+ return 1;
955
+ const dateA = new Date(Date.UTC(structA.year, structA.month - 1, structA.day));
956
+ const dateB = new Date(Date.UTC(structB.year, structB.month - 1, structB.day));
957
+ return dateA.getTime() - dateB.getTime() < 0
958
+ ? -1
959
+ : dateA.getTime() - dateB.getTime() > 0
960
+ ? 1
961
+ : 0;
962
+ }
963
+
964
+ class GaDatepickerComponent {
965
+ i18n = inject(GaDatepickerI18n);
966
+ valueAdapter = inject(GaDatepickerValueAdapter);
967
+ icons = {
968
+ ChevronLeft,
969
+ ChevronRight,
970
+ ChevronUp,
971
+ ChevronDown,
972
+ };
973
+ value = model(null);
974
+ min = input(null);
975
+ max = input(null);
976
+ // Internal struct representation
977
+ internalValue = computed(() => {
978
+ return this.valueAdapter.toStruct(this.value());
979
+ });
980
+ internalMinDate = computed(() => {
981
+ return this.valueAdapter.toStruct(this.min());
982
+ });
983
+ internalMaxDate = computed(() => {
984
+ return this.valueAdapter.toStruct(this.max());
985
+ });
986
+ viewMode = signal('day');
987
+ viewDate = signal(this.getInitialViewDate());
988
+ ngOnInit() {
989
+ // Initialize view date based on the initial value or today's date
990
+ this.viewDate.set(this.getInitialViewDate());
991
+ }
992
+ getInitialViewDate() {
993
+ // Try to use the initial value if available
994
+ const initialValue = this.valueAdapter.toStruct(this.value());
995
+ if (initialValue) {
996
+ return {
997
+ year: initialValue.year,
998
+ month: initialValue.month,
999
+ };
1000
+ }
1001
+ // Fallback to today's date, but respect min/max constraints
1002
+ const today = new Date();
1003
+ const todayStruct = {
1004
+ year: today.getFullYear(),
1005
+ month: today.getMonth() + 1, // Convert from 0-11 to 1-12
1006
+ day: today.getDate(),
1007
+ };
1008
+ const minStruct = this.valueAdapter.toStruct(this.min());
1009
+ const maxStruct = this.valueAdapter.toStruct(this.max());
1010
+ let targetDate = todayStruct;
1011
+ // If today is before min date, use min date
1012
+ if (minStruct) {
1013
+ const todayValue = todayStruct.year * 10000 + todayStruct.month * 100 + todayStruct.day;
1014
+ const minValue = minStruct.year * 10000 + minStruct.month * 100 + minStruct.day;
1015
+ if (todayValue < minValue) {
1016
+ targetDate = minStruct;
1017
+ }
1018
+ }
1019
+ // If today is after max date, use max date
1020
+ if (maxStruct) {
1021
+ const todayValue = todayStruct.year * 10000 + todayStruct.month * 100 + todayStruct.day;
1022
+ const maxValue = maxStruct.year * 10000 + maxStruct.month * 100 + maxStruct.day;
1023
+ if (todayValue > maxValue) {
1024
+ targetDate = maxStruct;
1025
+ }
1026
+ }
1027
+ return {
1028
+ year: targetDate.year,
1029
+ month: targetDate.month,
1030
+ };
1031
+ }
1032
+ weekDays = computed(() => this.i18n.weekDays);
1033
+ calendarDays = computed(() => {
1034
+ const viewStruct = this.viewDate();
1035
+ const year = viewStruct.year;
1036
+ const month = viewStruct.month;
1037
+ const firstDay = new Date(year, month - 1, 1); // Convert from 1-12 to 0-11
1038
+ const lastDay = new Date(year, month, 0); // month is already 1-12, so this gives us last day of month-1
1039
+ const startDate = new Date(firstDay);
1040
+ const startDayOfWeek = (firstDay.getDay() + 6) % 7;
1041
+ startDate.setDate(startDate.getDate() - startDayOfWeek);
1042
+ const days = [];
1043
+ const current = new Date(startDate);
1044
+ while (current <= lastDay || days.length % 7 !== 0) {
1045
+ days.push({
1046
+ year: current.getFullYear(),
1047
+ month: current.getMonth() + 1, // Convert from 0-11 to 1-12
1048
+ day: current.getDate(),
1049
+ });
1050
+ current.setDate(current.getDate() + 1);
1051
+ }
1052
+ return days;
1053
+ });
1054
+ months = computed(() => {
1055
+ return Array.from({ length: 12 }, (_, i) => ({
1056
+ index: i + 1, // Use 1-12 indexing
1057
+ name: this.i18n.monthNames[i],
1058
+ shortName: this.i18n.monthNamesShort[i],
1059
+ }));
1060
+ });
1061
+ years = computed(() => {
1062
+ const currentYear = this.viewDate().year;
1063
+ const startYear = Math.floor(currentYear / 10) * 10;
1064
+ return Array.from({ length: 25 }, (_, i) => startYear + i - 1);
1065
+ });
1066
+ selectDate(dateStruct) {
1067
+ if (this.isDateDisabled(dateStruct)) {
1068
+ return;
1069
+ }
1070
+ const externalValue = this.valueAdapter.fromStruct(dateStruct);
1071
+ this.value.set(externalValue);
1072
+ }
1073
+ selectMonth(monthIndex) {
1074
+ const currentView = this.viewDate();
1075
+ const newView = {
1076
+ year: currentView.year,
1077
+ month: monthIndex, // monthIndex is already 1-12 from months array
1078
+ };
1079
+ this.viewDate.set(newView);
1080
+ this.viewMode.set('day');
1081
+ }
1082
+ selectYear(year) {
1083
+ const currentView = this.viewDate();
1084
+ const newView = {
1085
+ year,
1086
+ month: currentView.month,
1087
+ };
1088
+ this.viewDate.set(newView);
1089
+ this.viewMode.set('month');
1090
+ }
1091
+ navigatePrevious() {
1092
+ const currentView = this.viewDate();
1093
+ let newView;
1094
+ switch (this.viewMode()) {
1095
+ case 'day': {
1096
+ const prevMonth = currentView.month === 1 ? 12 : currentView.month - 1; // Handle 1-12 indexing
1097
+ const prevYear = currentView.month === 1 ? currentView.year - 1 : currentView.year;
1098
+ newView = {
1099
+ year: prevYear,
1100
+ month: prevMonth,
1101
+ };
1102
+ break;
1103
+ }
1104
+ case 'month':
1105
+ newView = {
1106
+ year: currentView.year - 1,
1107
+ month: currentView.month,
1108
+ };
1109
+ break;
1110
+ case 'year':
1111
+ newView = {
1112
+ year: currentView.year - 10,
1113
+ month: currentView.month,
1114
+ };
1115
+ break;
1116
+ }
1117
+ this.viewDate.set(newView);
1118
+ }
1119
+ navigateNext() {
1120
+ const currentView = this.viewDate();
1121
+ let newView;
1122
+ switch (this.viewMode()) {
1123
+ case 'day': {
1124
+ const nextMonth = currentView.month === 12 ? 1 : currentView.month + 1; // Handle 1-12 indexing
1125
+ const nextYear = currentView.month === 12 ? currentView.year + 1 : currentView.year;
1126
+ newView = {
1127
+ year: nextYear,
1128
+ month: nextMonth,
1129
+ };
1130
+ break;
1131
+ }
1132
+ case 'month':
1133
+ newView = {
1134
+ year: currentView.year + 1,
1135
+ month: currentView.month,
1136
+ };
1137
+ break;
1138
+ case 'year':
1139
+ newView = {
1140
+ year: currentView.year + 10,
1141
+ month: currentView.month,
1142
+ };
1143
+ break;
1144
+ }
1145
+ this.viewDate.set(newView);
1146
+ }
1147
+ toggleMonthView() {
1148
+ this.viewMode.set(this.viewMode() === 'month' ? 'day' : 'month');
1149
+ }
1150
+ toggleYearView() {
1151
+ this.viewMode.set(this.viewMode() === 'year' ? 'day' : 'year');
1152
+ }
1153
+ isToday(dateStruct) {
1154
+ const today = new Date();
1155
+ const todayStruct = {
1156
+ year: today.getFullYear(),
1157
+ month: today.getMonth() + 1, // Convert from 0-11 to 1-12
1158
+ day: today.getDate(),
1159
+ };
1160
+ return compareStructs(dateStruct, todayStruct) === 0;
1161
+ }
1162
+ isSelected(dateStruct) {
1163
+ const selectedStruct = this.internalValue();
1164
+ return compareStructs(dateStruct, selectedStruct) === 0;
1165
+ }
1166
+ isCurrentMonth(dateStruct) {
1167
+ return dateStruct.month === this.viewDate().month;
1168
+ }
1169
+ isWeekend(dateStruct) {
1170
+ // Convert struct to Date to get day of week (convert month from 1-12 to 0-11)
1171
+ const date = new Date(dateStruct.year, dateStruct.month - 1, dateStruct.day);
1172
+ const day = date.getDay();
1173
+ return day === 0 || day === 6;
1174
+ }
1175
+ isDateDisabled(dateStruct) {
1176
+ const minStruct = this.internalMinDate();
1177
+ const maxStruct = this.internalMaxDate();
1178
+ if (minStruct) {
1179
+ const dateValue = dateStruct.year * 10000 + dateStruct.month * 100 + dateStruct.day;
1180
+ const minValue = minStruct.year * 10000 + minStruct.month * 100 + minStruct.day;
1181
+ if (dateValue < minValue) {
1182
+ return true;
1183
+ }
1184
+ }
1185
+ if (maxStruct) {
1186
+ const dateValue = dateStruct.year * 10000 + dateStruct.month * 100 + dateStruct.day;
1187
+ const maxValue = maxStruct.year * 10000 + maxStruct.month * 100 + maxStruct.day;
1188
+ if (dateValue > maxValue) {
1189
+ return true;
1190
+ }
1191
+ }
1192
+ return false;
1193
+ }
1194
+ isMonthDisabled(monthIndex) {
1195
+ const minStruct = this.internalMinDate();
1196
+ const maxStruct = this.internalMaxDate();
1197
+ const year = this.viewDate().year;
1198
+ if (minStruct) {
1199
+ if (year < minStruct.year ||
1200
+ (year === minStruct.year && monthIndex < minStruct.month)) {
1201
+ return true;
1202
+ }
1203
+ }
1204
+ if (maxStruct) {
1205
+ if (year > maxStruct.year ||
1206
+ (year === maxStruct.year && monthIndex > maxStruct.month)) {
1207
+ return true;
1208
+ }
1209
+ }
1210
+ return false;
1211
+ }
1212
+ isYearDisabled(year) {
1213
+ const minStruct = this.internalMinDate();
1214
+ const maxStruct = this.internalMaxDate();
1215
+ if (minStruct && year < minStruct.year) {
1216
+ return true;
1217
+ }
1218
+ if (maxStruct && year > maxStruct.year) {
1219
+ return true;
1220
+ }
1221
+ return false;
1222
+ }
1223
+ isSelectedMonth(monthIndex) {
1224
+ const selectedStruct = this.internalValue();
1225
+ if (!selectedStruct)
1226
+ return false;
1227
+ return (selectedStruct.month === monthIndex &&
1228
+ selectedStruct.year === this.viewDate().year);
1229
+ }
1230
+ isSelectedYear(year) {
1231
+ const selectedStruct = this.internalValue();
1232
+ return selectedStruct ? selectedStruct.year === year : false;
1233
+ }
1234
+ getMonthName(monthIndex) {
1235
+ return this.i18n.monthNames[monthIndex - 1]; // Convert from 1-12 to 0-11 for array access
1236
+ }
1237
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1238
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.4", type: GaDatepickerComponent, isStandalone: true, selector: "ga-datepicker", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { classAttribute: "ga-calendar" }, ngImport: i0, template: "<div class=\"ga-calendar__header\">\n <div class=\"ga-calendar__month-year\">\n <button\n type=\"button\"\n class=\"ga-calendar__month-year-button\"\n (click)=\"toggleMonthView()\"\n [attr.aria-label]=\"i18n.selectMonthLabel\"\n >\n {{ getMonthName(viewDate().month) }}\n <ga-icon\n [icon]=\"viewMode() === 'month' ? icons.ChevronUp : icons.ChevronDown\"\n size=\"16\"\n />\n </button>\n <button\n type=\"button\"\n class=\"ga-calendar__month-year-button\"\n (click)=\"toggleYearView()\"\n [attr.aria-label]=\"i18n.selectYearLabel\"\n >\n {{ viewDate().year }}\n <ga-icon\n [icon]=\"viewMode() === 'year' ? icons.ChevronUp : icons.ChevronDown\"\n size=\"16\"\n />\n </button>\n </div>\n @if (viewMode() !== 'month') {\n <div class=\"ga-calendar__navigation\">\n <button\n type=\"button\"\n class=\"ga-calendar__navigation-button\"\n (click)=\"navigatePrevious()\"\n [attr.aria-label]=\"i18n.previousLabel\"\n >\n <ga-icon [icon]=\"icons.ChevronLeft\" size=\"24\" />\n </button>\n <button\n type=\"button\"\n class=\"ga-calendar__navigation-button\"\n (click)=\"navigateNext()\"\n [attr.aria-label]=\"i18n.nextLabel\"\n >\n <ga-icon [icon]=\"icons.ChevronRight\" size=\"24\" />\n </button>\n </div>\n }\n</div>\n\n@switch (viewMode()) {\n @case ('day') {\n <div class=\"ga-calendar__weekdays\">\n @for (day of weekDays(); track day) {\n <div class=\"ga-calendar__weekday\">{{ day }}</div>\n }\n </div>\n <div class=\"ga-calendar__selection ga-calendar__selection--day\">\n @for (\n dateStruct of calendarDays();\n track dateStruct.year + '-' + dateStruct.month + '-' + dateStruct.day\n ) {\n <button\n type=\"button\"\n class=\"ga-calendar__day\"\n [class.ga-calendar__day--selected]=\"isSelected(dateStruct)\"\n [class.ga-calendar__day--current]=\"isToday(dateStruct)\"\n [class.ga-calendar__day--disabled]=\"isDateDisabled(dateStruct)\"\n [class.ga-calendar__day--weekend]=\"isWeekend(dateStruct)\"\n [disabled]=\"isDateDisabled(dateStruct)\"\n (click)=\"selectDate(dateStruct)\"\n >\n {{ dateStruct.day }}\n </button>\n }\n </div>\n }\n @case ('month') {\n <div class=\"ga-calendar__selection ga-calendar__selection--month\">\n @for (month of months(); track month.index) {\n <button\n type=\"button\"\n class=\"ga-calendar__month\"\n [class.ga-calendar__month--selected]=\"isSelectedMonth(month.index)\"\n [class.ga-calendar__month--disabled]=\"isMonthDisabled(month.index)\"\n [disabled]=\"isMonthDisabled(month.index)\"\n (click)=\"selectMonth(month.index)\"\n >\n {{ month.shortName }}\n </button>\n }\n </div>\n }\n @case ('year') {\n <div class=\"ga-calendar__selection ga-calendar__selection--year\">\n @for (year of years(); track year) {\n <button\n type=\"button\"\n class=\"ga-calendar__year\"\n [class.ga-calendar__year--selected]=\"isSelectedYear(year)\"\n [class.ga-calendar__year--disabled]=\"isYearDisabled(year)\"\n [disabled]=\"isYearDisabled(year)\"\n (click)=\"selectYear(year)\"\n >\n {{ year }}\n </button>\n }\n </div>\n }\n}\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: GaIconModule }, { kind: "component", type: GaIconComponent, selector: "ga-icon", inputs: ["icon", "size", "color", "strokeWidth"] }] });
1239
+ }
1240
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerComponent, decorators: [{
1241
+ type: Component,
1242
+ args: [{ selector: 'ga-datepicker', imports: [GaIconModule], host: {
1243
+ class: 'ga-calendar',
1244
+ }, template: "<div class=\"ga-calendar__header\">\n <div class=\"ga-calendar__month-year\">\n <button\n type=\"button\"\n class=\"ga-calendar__month-year-button\"\n (click)=\"toggleMonthView()\"\n [attr.aria-label]=\"i18n.selectMonthLabel\"\n >\n {{ getMonthName(viewDate().month) }}\n <ga-icon\n [icon]=\"viewMode() === 'month' ? icons.ChevronUp : icons.ChevronDown\"\n size=\"16\"\n />\n </button>\n <button\n type=\"button\"\n class=\"ga-calendar__month-year-button\"\n (click)=\"toggleYearView()\"\n [attr.aria-label]=\"i18n.selectYearLabel\"\n >\n {{ viewDate().year }}\n <ga-icon\n [icon]=\"viewMode() === 'year' ? icons.ChevronUp : icons.ChevronDown\"\n size=\"16\"\n />\n </button>\n </div>\n @if (viewMode() !== 'month') {\n <div class=\"ga-calendar__navigation\">\n <button\n type=\"button\"\n class=\"ga-calendar__navigation-button\"\n (click)=\"navigatePrevious()\"\n [attr.aria-label]=\"i18n.previousLabel\"\n >\n <ga-icon [icon]=\"icons.ChevronLeft\" size=\"24\" />\n </button>\n <button\n type=\"button\"\n class=\"ga-calendar__navigation-button\"\n (click)=\"navigateNext()\"\n [attr.aria-label]=\"i18n.nextLabel\"\n >\n <ga-icon [icon]=\"icons.ChevronRight\" size=\"24\" />\n </button>\n </div>\n }\n</div>\n\n@switch (viewMode()) {\n @case ('day') {\n <div class=\"ga-calendar__weekdays\">\n @for (day of weekDays(); track day) {\n <div class=\"ga-calendar__weekday\">{{ day }}</div>\n }\n </div>\n <div class=\"ga-calendar__selection ga-calendar__selection--day\">\n @for (\n dateStruct of calendarDays();\n track dateStruct.year + '-' + dateStruct.month + '-' + dateStruct.day\n ) {\n <button\n type=\"button\"\n class=\"ga-calendar__day\"\n [class.ga-calendar__day--selected]=\"isSelected(dateStruct)\"\n [class.ga-calendar__day--current]=\"isToday(dateStruct)\"\n [class.ga-calendar__day--disabled]=\"isDateDisabled(dateStruct)\"\n [class.ga-calendar__day--weekend]=\"isWeekend(dateStruct)\"\n [disabled]=\"isDateDisabled(dateStruct)\"\n (click)=\"selectDate(dateStruct)\"\n >\n {{ dateStruct.day }}\n </button>\n }\n </div>\n }\n @case ('month') {\n <div class=\"ga-calendar__selection ga-calendar__selection--month\">\n @for (month of months(); track month.index) {\n <button\n type=\"button\"\n class=\"ga-calendar__month\"\n [class.ga-calendar__month--selected]=\"isSelectedMonth(month.index)\"\n [class.ga-calendar__month--disabled]=\"isMonthDisabled(month.index)\"\n [disabled]=\"isMonthDisabled(month.index)\"\n (click)=\"selectMonth(month.index)\"\n >\n {{ month.shortName }}\n </button>\n }\n </div>\n }\n @case ('year') {\n <div class=\"ga-calendar__selection ga-calendar__selection--year\">\n @for (year of years(); track year) {\n <button\n type=\"button\"\n class=\"ga-calendar__year\"\n [class.ga-calendar__year--selected]=\"isSelectedYear(year)\"\n [class.ga-calendar__year--disabled]=\"isYearDisabled(year)\"\n [disabled]=\"isYearDisabled(year)\"\n (click)=\"selectYear(year)\"\n >\n {{ year }}\n </button>\n }\n </div>\n }\n}\n", styles: [":host{display:block}\n"] }]
1245
+ }] });
1246
+
1247
+ class GaFormFieldConnector {
1248
+ controlDisabled = signal(false);
1249
+ controlId = signal(null);
1250
+ labelId = signal(null);
1251
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFormFieldConnector, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1252
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFormFieldConnector });
1253
+ }
1254
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFormFieldConnector, decorators: [{
1255
+ type: Injectable
1256
+ }] });
1257
+
1258
+ let nextUniqueId$7 = 0;
1259
+ class GaInputDirective {
1260
+ uniqueId = `ga-input-${++nextUniqueId$7}`;
1261
+ formFieldConnector = inject(GaFormFieldConnector, {
1262
+ optional: true,
1263
+ });
1264
+ hasWrapper = inject(GaInputComponent, { optional: true });
1265
+ renderer = inject(Renderer2);
1266
+ elementRef = inject(ElementRef);
1267
+ implicitNgControlState = injectNgControlState();
1268
+ invalidInput = input(null, {
1269
+ alias: 'invalid',
1270
+ transform: booleanAttribute,
1271
+ });
1272
+ idInput = input(undefined, { alias: 'id' });
1273
+ disabledInput = input(undefined, {
1274
+ alias: 'disabled',
1275
+ transform: booleanAttribute,
1276
+ });
1277
+ invalid = computed(() => {
1278
+ return this.invalidInput() ?? this.implicitNgControlState.inError();
1279
+ });
1280
+ id = computed(() => {
1281
+ return this.idInput() ?? this.uniqueId;
1282
+ });
1283
+ disabled = computed(() => {
1284
+ return this.disabledInput() ?? this.implicitNgControlState.disabled();
1285
+ });
1286
+ constructor(placeholder) {
1287
+ const formFieldConnector = this.formFieldConnector;
1288
+ if (formFieldConnector) {
1289
+ effect(() => formFieldConnector.controlDisabled.set(this.disabled()));
1290
+ effect(() => formFieldConnector.controlId.set(this.id()));
1291
+ }
1292
+ if (!placeholder) {
1293
+ // a workaround till https://github.com/visma-software-nordic/gaia-styles/issues/108 is fixed
1294
+ this.renderer.setAttribute(this.elementRef.nativeElement, 'placeholder', '');
1295
+ }
1296
+ }
1297
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaInputDirective, deps: [{ token: 'placeholder', attribute: true }], target: i0.ɵɵFactoryTarget.Component });
1298
+ 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()", "attr.disabled": "disabled() ? \"\" : null" } }, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
1299
+ }
1300
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaInputDirective, decorators: [{
1301
+ type: Component,
1302
+ args: [{
1303
+ // eslint-disable-next-line @angular-eslint/component-selector
1304
+ selector: '[gaInput]',
1305
+ template: '',
1306
+ changeDetection: ChangeDetectionStrategy.OnPush,
1307
+ host: {
1308
+ '[attr.id]': 'id()',
1309
+ '[class.ga-input]': '!hasWrapper',
1310
+ '[class.ga-input--invalid]': '!hasWrapper && invalid()',
1311
+ '[attr.disabled]': 'disabled() ? "" : null',
1312
+ },
1313
+ }]
1314
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
1315
+ type: Attribute,
1316
+ args: ['placeholder']
1317
+ }] }] });
1318
+
1319
+ class GaInputComponent {
1320
+ gaInput = contentChild.required(GaInputDirective);
1321
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1322
+ 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 }], hostDirectives: [{ directive: i1$1.CdkOverlayOrigin }], ngImport: i0, template: `<ng-content />`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
1323
+ }
1324
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaInputComponent, decorators: [{
1325
+ type: Component,
1326
+ args: [{
1327
+ selector: 'ga-input',
1328
+ template: `<ng-content />`,
1329
+ changeDetection: ChangeDetectionStrategy.OnPush,
1330
+ hostDirectives: [CdkOverlayOrigin],
1331
+ host: {
1332
+ class: 'ga-input',
1333
+ '[class.ga-input--invalid]': 'gaInput().invalid()',
1334
+ },
1335
+ }]
1336
+ }] });
1337
+
1338
+ class GaDatepickerToggleComponent {
1339
+ icons = { CalendarDays };
1340
+ i18n = inject(GaDatepickerI18n);
1341
+ gaInput = inject(GaInputComponent);
1342
+ valueAdapter = inject(GaDatepickerValueAdapter);
1343
+ injector = inject(Injector);
1344
+ overlayOrigin = inject(CdkOverlayOrigin);
1345
+ repositionScrollStrategy = createRepositionScrollStrategy(this.injector);
1346
+ positions = [
1347
+ {
1348
+ originX: 'start',
1349
+ originY: 'bottom',
1350
+ overlayX: 'start',
1351
+ overlayY: 'top',
1352
+ offsetY: 8,
1353
+ },
1354
+ {
1355
+ originX: 'start',
1356
+ originY: 'top',
1357
+ overlayX: 'start',
1358
+ overlayY: 'bottom',
1359
+ offsetY: -8,
1360
+ },
1361
+ {
1362
+ originX: 'end',
1363
+ originY: 'bottom',
1364
+ overlayX: 'end',
1365
+ overlayY: 'top',
1366
+ offsetY: 8,
1367
+ },
1368
+ {
1369
+ originX: 'end',
1370
+ originY: 'top',
1371
+ overlayX: 'end',
1372
+ overlayY: 'bottom',
1373
+ offsetY: -8,
1374
+ },
1375
+ ];
1376
+ _isOpen = signal(false);
1377
+ isOpen = this._isOpen.asReadonly();
1378
+ for = input.required();
1379
+ toggle() {
1380
+ if (this._isOpen()) {
1381
+ this.close();
1382
+ }
1383
+ else {
1384
+ this.open();
1385
+ }
1386
+ }
1387
+ open() {
1388
+ if (this.for().disabled() || this._isOpen()) {
1389
+ return;
1390
+ }
1391
+ this._isOpen.set(true);
1392
+ }
1393
+ close() {
1394
+ if (!this._isOpen()) {
1395
+ return;
1396
+ }
1397
+ this._isOpen.set(false);
1398
+ }
1399
+ onDatepickerValueChange(value) {
1400
+ this.for().updateValue(value, { updateView: true, emitToNgModel: true });
1401
+ if (value) {
1402
+ this.close();
1403
+ }
1404
+ }
1405
+ setToday() {
1406
+ const today = new Date();
1407
+ const todayStruct = {
1408
+ year: today.getFullYear(),
1409
+ month: today.getMonth() + 1,
1410
+ day: today.getDate(),
1411
+ };
1412
+ const todayValue = this.valueAdapter.fromStruct(todayStruct);
1413
+ this.for().updateValue(todayValue, {
1414
+ updateView: true,
1415
+ emitToNgModel: true,
1416
+ });
1417
+ this.close();
1418
+ }
1419
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerToggleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1420
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.0.4", type: GaDatepickerToggleComponent, isStandalone: true, selector: "ga-datepicker-toggle", inputs: { for: { classPropertyName: "for", publicName: "for", isSignal: true, isRequired: true, transformFunction: null } }, host: { listeners: { "keydown.escape": "close()" } }, ngImport: i0, template: "<button\n type=\"button\"\n class=\"ga-datepicker-toggle\"\n [disabled]=\"for().disabled()\"\n (click)=\"toggle()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"true\"\n [attr.aria-label]=\"i18n.openCalendarLabel\"\n tabindex=\"-1\"\n>\n <ga-icon [icon]=\"icons.CalendarDays\" size=\"24\" />\n</button>\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayLockPosition\n [cdkConnectedOverlayOrigin]=\"overlayOrigin\"\n [cdkConnectedOverlayOpen]=\"isOpen()\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayScrollStrategy]=\"repositionScrollStrategy\"\n (overlayOutsideClick)=\"close()\"\n (overlayKeydown)=\"$event.code === 'Escape' && close()\"\n>\n <div class=\"ga-datepicker\">\n <ga-datepicker\n [value]=\"for().value()\"\n (valueChange)=\"onDatepickerValueChange($event)\"\n [min]=\"for().min()\"\n [max]=\"for().max()\"\n />\n <div class=\"ga-datepicker__footer\">\n <button type=\"button\" gaButton (click)=\"setToday()\">\n {{ i18n.todayButtonLabel }}\n </button>\n </div>\n </div>\n</ng-template>\n", styles: [".ga-datepicker__footer{text-align:center}\n"], dependencies: [{ kind: "ngmodule", type: GaIconModule }, { kind: "component", type: GaIconComponent, selector: "ga-icon", inputs: ["icon", "size", "color", "strokeWidth"] }, { kind: "ngmodule", type: GaButtonModule }, { kind: "component", type: GaButtonDirective, selector: "button[gaButton], a[gaButton]", inputs: ["gaButton", "gaButtonLoading", "gaButtonLoadingLabel", "disabled"] }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i1$1.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: GaDatepickerComponent, selector: "ga-datepicker", inputs: ["value", "min", "max"], outputs: ["valueChange"] }], encapsulation: i0.ViewEncapsulation.None });
1421
+ }
1422
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerToggleComponent, decorators: [{
1423
+ type: Component,
1424
+ args: [{ selector: 'ga-datepicker-toggle', imports: [GaIconModule, GaButtonModule, OverlayModule, GaDatepickerComponent], encapsulation: ViewEncapsulation.None, host: {
1425
+ '(keydown.escape)': 'close()',
1426
+ }, template: "<button\n type=\"button\"\n class=\"ga-datepicker-toggle\"\n [disabled]=\"for().disabled()\"\n (click)=\"toggle()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"true\"\n [attr.aria-label]=\"i18n.openCalendarLabel\"\n tabindex=\"-1\"\n>\n <ga-icon [icon]=\"icons.CalendarDays\" size=\"24\" />\n</button>\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayLockPosition\n [cdkConnectedOverlayOrigin]=\"overlayOrigin\"\n [cdkConnectedOverlayOpen]=\"isOpen()\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayScrollStrategy]=\"repositionScrollStrategy\"\n (overlayOutsideClick)=\"close()\"\n (overlayKeydown)=\"$event.code === 'Escape' && close()\"\n>\n <div class=\"ga-datepicker\">\n <ga-datepicker\n [value]=\"for().value()\"\n (valueChange)=\"onDatepickerValueChange($event)\"\n [min]=\"for().min()\"\n [max]=\"for().max()\"\n />\n <div class=\"ga-datepicker__footer\">\n <button type=\"button\" gaButton (click)=\"setToday()\">\n {{ i18n.todayButtonLabel }}\n </button>\n </div>\n </div>\n</ng-template>\n", styles: [".ga-datepicker__footer{text-align:center}\n"] }]
1427
+ }] });
1428
+
1429
+ function GA_DATEPICKER_PARSER_FORMATTER_FACTORY() {
1430
+ return new GaDatepickerParserFormatterDefault();
1431
+ }
1432
+ /**
1433
+ * Converts between the internal `GaDatepickerStruct` model presentation and a `string` that is displayed in the input element.
1434
+ */
1435
+ class GaDatepickerParserFormatter {
1436
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerParserFormatter, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1437
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerParserFormatter, providedIn: 'root', useFactory: GA_DATEPICKER_PARSER_FORMATTER_FACTORY });
1438
+ }
1439
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerParserFormatter, decorators: [{
1440
+ type: Injectable,
1441
+ args: [{
1442
+ providedIn: 'root',
1443
+ useFactory: GA_DATEPICKER_PARSER_FORMATTER_FACTORY,
1444
+ }]
1445
+ }] });
1446
+ const GA_DEFAULT_DATEPICKER_FORMATS = {
1447
+ 'en-US': {
1448
+ input: [
1449
+ 'yyyy-MM-dd',
1450
+ 'M d yy',
1451
+ 'M d yyyy',
1452
+ 'M/d/yy',
1453
+ 'M/d/yyyy',
1454
+ 'M.d.yy',
1455
+ 'M.d.yyyy',
1456
+ 'M-d-yy',
1457
+ 'M-d-yyyy',
1458
+ ],
1459
+ output: 'MM/dd/yyyy',
1460
+ },
1461
+ 'en-GB': {
1462
+ input: [
1463
+ 'yyyy-MM-dd',
1464
+ 'd M yy',
1465
+ 'd M yyyy',
1466
+ 'd/M/yy',
1467
+ 'd/M/yyyy',
1468
+ 'd.M.yy',
1469
+ 'd.M.yyyy',
1470
+ 'd-M-yy',
1471
+ 'd-M-yyyy',
1472
+ ],
1473
+ output: 'dd/MM/yyyy',
1474
+ },
1475
+ 'da-dK': {
1476
+ input: [
1477
+ 'yyyy-MM-dd',
1478
+ 'd M yyyy',
1479
+ 'd M yy',
1480
+ 'd.M.yy',
1481
+ 'd.M.yyyy',
1482
+ 'd/M/yy',
1483
+ 'd/M/yyyy',
1484
+ 'd-M-yy',
1485
+ 'd-M-yyyy',
1486
+ ],
1487
+ output: 'dd.MM.yyyy',
1488
+ },
1489
+ 'fi-FI': {
1490
+ input: [
1491
+ 'yyyy-MM-dd',
1492
+ 'd M yy',
1493
+ 'd M yyyy',
1494
+ 'd.M.yy',
1495
+ 'd.M.yyyy',
1496
+ 'd/M/yy',
1497
+ 'd/M/yyyy',
1498
+ 'd-M-yy',
1499
+ 'd-M-yyyy',
1500
+ ],
1501
+ output: 'dd.MM.yyyy',
1502
+ },
1503
+ 'nb-NO': {
1504
+ input: [
1505
+ 'yyyy-MM-dd',
1506
+ 'd M yy',
1507
+ 'd M yyyy',
1508
+ 'd.M.yy',
1509
+ 'd.M.yyyy',
1510
+ 'd/M/yy',
1511
+ 'd/M/yyyy',
1512
+ 'd-M-yy',
1513
+ 'd-M-yyyy',
1514
+ ],
1515
+ output: 'dd.MM.yyyy',
1516
+ },
1517
+ 'nn-NO': {
1518
+ input: [
1519
+ 'yyyy-MM-dd',
1520
+ 'd M yy',
1521
+ 'd M yyyy',
1522
+ 'd.M.yy',
1523
+ 'd.M.yyyy',
1524
+ 'd/M/yy',
1525
+ 'd/M/yyyy',
1526
+ 'd-M-yy',
1527
+ 'd-M-yyyy',
1528
+ ],
1529
+ output: 'dd.MM.yyyy',
1530
+ },
1531
+ 'sv-SE': {
1532
+ input: [
1533
+ 'yyyy-MM-dd',
1534
+ 'yy M d',
1535
+ 'yyyy M d',
1536
+ 'yy-M-d',
1537
+ 'yyyy-M-d',
1538
+ 'yy/M/d',
1539
+ 'yyyy/M/d',
1540
+ 'yy.M.d',
1541
+ 'yyyy.M.d',
1542
+ 'yyMMdd',
1543
+ 'yyyyMMdd',
1544
+ ],
1545
+ output: 'yyyy-MM-dd',
1546
+ },
1547
+ };
1548
+ const GA_DATE_PARSER_FORMATTER_CONFIG = new InjectionToken('GA_DATE_PARSER_FORMATTER_CONFIG', { providedIn: 'root', factory: () => GA_DEFAULT_DATEPICKER_FORMATS });
1549
+ function extendGaDateParserFormatter(formats) {
1550
+ return {
1551
+ provide: GA_DATE_PARSER_FORMATTER_CONFIG,
1552
+ useValue: { ...GA_DEFAULT_DATEPICKER_FORMATS, ...formats },
1553
+ };
1554
+ }
1555
+ class GaDatepickerParserFormatterDefault extends GaDatepickerParserFormatter {
1556
+ /** @ignore */
1557
+ locale = inject(LOCALE_ID);
1558
+ /** @ignore */
1559
+ formats = inject(GA_DATE_PARSER_FORMATTER_CONFIG);
1560
+ parse(value) {
1561
+ if (!value || typeof value !== 'string') {
1562
+ return null;
1563
+ }
1564
+ const trimmedValue = value.trim();
1565
+ if (!trimmedValue) {
1566
+ return null;
1567
+ }
1568
+ let config = this.formats[this.locale];
1569
+ if (!config) {
1570
+ this.printUnknownLocaleWarning();
1571
+ config = GA_DEFAULT_DATEPICKER_FORMATS['en-GB'];
1572
+ }
1573
+ for (const format of config.input) {
1574
+ const regexp = this.dateFormatToRegexp(format);
1575
+ const match = trimmedValue.match(regexp);
1576
+ if (match) {
1577
+ const yearIndex = format.indexOf('y');
1578
+ const monthIndex = format.indexOf('M');
1579
+ const dayIndex = format.indexOf('d');
1580
+ const sortedIndexes = [yearIndex, monthIndex, dayIndex].sort();
1581
+ const yearGroup = sortedIndexes.indexOf(yearIndex) + 1;
1582
+ const monthGroup = sortedIndexes.indexOf(monthIndex) + 1;
1583
+ const dayGroup = sortedIndexes.indexOf(dayIndex) + 1;
1584
+ const year = this.addYearPadding(+match[yearGroup]);
1585
+ const month = +match[monthGroup];
1586
+ const day = +match[dayGroup];
1587
+ if (month <= 0 || month > 12) {
1588
+ // invalid month
1589
+ return null;
1590
+ }
1591
+ const daysInMonth = new Date(year, month, 0).getDate();
1592
+ if (day <= 0 || day > daysInMonth) {
1593
+ // invalid day
1594
+ return null;
1595
+ }
1596
+ return { year, month, day };
1597
+ }
1598
+ }
1599
+ return null;
1600
+ }
1601
+ format(date) {
1602
+ if (!date) {
1603
+ return '';
1604
+ }
1605
+ let format = this.formats[this.locale];
1606
+ if (!format) {
1607
+ this.printUnknownLocaleWarning();
1608
+ format = GA_DEFAULT_DATEPICKER_FORMATS['en-GB'];
1609
+ }
1610
+ return this.formatDate(date, format.output);
1611
+ }
1612
+ formatDate(date, format) {
1613
+ const year = date.year.toString();
1614
+ const month = date.month.toString().padStart(2, '0');
1615
+ const day = date.day.toString().padStart(2, '0');
1616
+ return format
1617
+ .replace(/yyyy/g, year)
1618
+ .replace(/MM/g, month)
1619
+ .replace(/dd/g, day);
1620
+ }
1621
+ dateFormatToRegexp(format) {
1622
+ const pattern = '^' +
1623
+ format
1624
+ // / to \/
1625
+ .replace(/\//g, '\\/')
1626
+ // . to \.
1627
+ .replace(/\./g, '\\.')
1628
+ .replace(/(d+)/, '(\\d{1,2})')
1629
+ .replace(/(yyyy)/, '(\\d{4})')
1630
+ .replace(/(yy)/, '(\\d{2})')
1631
+ .replace(/(M+)/, '(\\d{1,2})') +
1632
+ '$';
1633
+ return new RegExp(pattern);
1634
+ }
1635
+ addYearPadding(year) {
1636
+ if (year < 100) {
1637
+ return 2000 + year;
1638
+ }
1639
+ return year;
1640
+ }
1641
+ printUnknownLocaleWarning() {
1642
+ console.warn(`Default datepicker parser-formatter does not have predefined formats for "${this.locale}" locale. Please provide custom 'GaDatepickerParserFormatter' class. Now defaults to "en-GB".`);
1643
+ }
1644
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerParserFormatterDefault, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
1645
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerParserFormatterDefault });
1646
+ }
1647
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerParserFormatterDefault, decorators: [{
1648
+ type: Injectable
1649
+ }] });
1650
+ function provideGaDatepickerParserFormatter(value) {
1651
+ if (isClass(value)) {
1652
+ return { provide: GaDatepickerParserFormatter, useClass: value };
1653
+ }
1654
+ return typeof value === 'function'
1655
+ ? { provide: GaDatepickerParserFormatter, useFactory: value }
1656
+ : { provide: GaDatepickerParserFormatter, useValue: value };
1657
+ }
1658
+
1659
+ class GaDatepickerInputDirective {
1660
+ inputElRef = inject(ElementRef, { self: true });
1661
+ parserFormatter = inject(GaDatepickerParserFormatter);
1662
+ valueAdapter = inject(GaDatepickerValueAdapter);
1663
+ // Native value control (alternative to Angular forms)
1664
+ valueInput = input(null, { alias: 'value' });
1665
+ disabledInput = input(null, {
1666
+ alias: 'disabled',
1667
+ transform: booleanAttribute,
1668
+ });
1669
+ min = input(null);
1670
+ max = input(null);
1671
+ dateInput = output();
1672
+ dateChange = output();
1673
+ value = linkedSignal(() => this.valueInput());
1674
+ dateStruct = computed(() => this.valueAdapter.toStruct(this.value()));
1675
+ disabled = linkedSignal(() => !!this.disabledInput());
1676
+ lastEmittedStruct = signal(null);
1677
+ lastValueValid = signal(false);
1678
+ onNgChangeFn;
1679
+ onNgTouchedFn;
1680
+ constructor() {
1681
+ effect(() => {
1682
+ this.valueInput(); // explicit call to track value input changes
1683
+ this.lastValueValid.set(true);
1684
+ untracked(() => this.formatValue());
1685
+ });
1686
+ }
1687
+ onInput(event) {
1688
+ const target = event.target;
1689
+ // Parse the input value
1690
+ const parsedStruct = this.parserFormatter.parse(target.value);
1691
+ const newValue = this.valueAdapter.fromStruct(parsedStruct);
1692
+ this.lastValueValid.set(!target.value || parsedStruct !== null);
1693
+ // Only update if the parsed value is different from current value
1694
+ if (compareStructs(parsedStruct, this.dateStruct()) !== 0) {
1695
+ this.value.set(newValue);
1696
+ this.dateInput.emit(newValue);
1697
+ }
1698
+ this.onNgChangeFn?.(newValue);
1699
+ }
1700
+ onBlur() {
1701
+ if (this.dateStruct()) {
1702
+ this.formatValue();
1703
+ }
1704
+ if (compareStructs(this.dateStruct(), this.lastEmittedStruct()) !== 0) {
1705
+ this.dateChange.emit(this.value());
1706
+ this.lastEmittedStruct.set(this.dateStruct());
1707
+ }
1708
+ this.onNgTouchedFn?.();
1709
+ }
1710
+ formatValue() {
1711
+ const value = this.dateStruct();
1712
+ const formattedValue = this.parserFormatter.format(value);
1713
+ this.inputElRef.nativeElement.value = formattedValue;
1714
+ }
1715
+ updateValue(value, { updateView, emitToNgModel, } = {}) {
1716
+ this.value.set(value);
1717
+ this.lastValueValid.set(true);
1718
+ if (updateView) {
1719
+ this.formatValue();
1720
+ }
1721
+ if (emitToNgModel) {
1722
+ this.onNgTouchedFn?.();
1723
+ this.onNgChangeFn?.(value);
1724
+ }
1725
+ }
1726
+ // ControlValueAccessor implementation
1727
+ writeValue(value) {
1728
+ this.updateValue(value, { updateView: true });
1729
+ }
1730
+ registerOnChange(fn) {
1731
+ this.onNgChangeFn = fn;
1732
+ }
1733
+ registerOnTouched(fn) {
1734
+ this.onNgTouchedFn = fn;
1735
+ }
1736
+ setDisabledState(isDisabled) {
1737
+ this.disabled.set(isDisabled);
1738
+ }
1739
+ validate(control) {
1740
+ const { value } = control;
1741
+ if (!this.lastValueValid()) {
1742
+ return { dateFormat: { actual: this.inputElRef.nativeElement.value } };
1743
+ }
1744
+ if (value === null) {
1745
+ return null;
1746
+ }
1747
+ const valueStruct = this.valueAdapter.toStruct(value);
1748
+ if (this.min()) {
1749
+ const minDateStruct = this.valueAdapter.toStruct(this.min());
1750
+ if (minDateStruct && compareStructs(valueStruct, minDateStruct) === -1) {
1751
+ return { minDate: { actual: value, min: this.min() } };
1752
+ }
1753
+ }
1754
+ if (this.max()) {
1755
+ const maxDateStruct = this.valueAdapter.toStruct(this.max());
1756
+ if (maxDateStruct && compareStructs(valueStruct, maxDateStruct) === 1) {
1757
+ return { maxDate: { actual: value, max: this.max() } };
1758
+ }
1759
+ }
1760
+ return null;
1761
+ }
1762
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerInputDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1763
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.0.4", type: GaDatepickerInputDirective, isStandalone: true, selector: "input[gaDatepickerInput]", inputs: { valueInput: { classPropertyName: "valueInput", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dateInput: "dateInput", dateChange: "dateChange" }, host: { listeners: { "blur": "onBlur()", "input": "onInput($event)" }, properties: { "disabled": "disabled()" } }, providers: [
1764
+ {
1765
+ provide: NG_VALUE_ACCESSOR,
1766
+ useExisting: forwardRef(() => GaDatepickerInputDirective),
1767
+ multi: true,
1768
+ },
1769
+ {
1770
+ provide: NG_VALIDATORS,
1771
+ useExisting: forwardRef(() => GaDatepickerInputDirective),
1772
+ multi: true,
1773
+ },
1774
+ ], exportAs: ["gaDatepickerInput"], ngImport: i0 });
1775
+ }
1776
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerInputDirective, decorators: [{
1777
+ type: Directive,
1778
+ args: [{
1779
+ selector: 'input[gaDatepickerInput]',
1780
+ exportAs: 'gaDatepickerInput',
1781
+ providers: [
1782
+ {
1783
+ provide: NG_VALUE_ACCESSOR,
1784
+ useExisting: forwardRef(() => GaDatepickerInputDirective),
1785
+ multi: true,
1786
+ },
1787
+ {
1788
+ provide: NG_VALIDATORS,
1789
+ useExisting: forwardRef(() => GaDatepickerInputDirective),
1790
+ multi: true,
1791
+ },
1792
+ ],
1793
+ host: {
1794
+ '[disabled]': 'disabled()',
1795
+ '(blur)': 'onBlur()',
1796
+ '(input)': 'onInput($event)',
1797
+ },
1798
+ }]
1799
+ }], ctorParameters: () => [] });
1800
+
1801
+ class GaDatepickerModule {
1802
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1803
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerModule, imports: [GaDatepickerComponent,
1804
+ GaDatepickerToggleComponent,
1805
+ GaDatepickerInputDirective], exports: [GaDatepickerComponent,
1806
+ GaDatepickerToggleComponent,
1807
+ GaDatepickerInputDirective] });
1808
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerModule, imports: [GaDatepickerComponent,
1809
+ GaDatepickerToggleComponent] });
1810
+ }
1811
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerModule, decorators: [{
1812
+ type: NgModule,
1813
+ args: [{
1814
+ imports: [
1815
+ GaDatepickerComponent,
1816
+ GaDatepickerToggleComponent,
1817
+ GaDatepickerInputDirective,
1818
+ ],
1819
+ exports: [
1820
+ GaDatepickerComponent,
1821
+ GaDatepickerToggleComponent,
1822
+ GaDatepickerInputDirective,
1823
+ ],
1824
+ }]
1825
+ }] });
1826
+
1827
+ class GaDatepickerNativeUtcValueAdapter extends GaDatepickerValueAdapter {
1828
+ /**
1829
+ * Converts Date to internal struct representation
1830
+ * Uses UTC to avoid timezone issues and normalizes to midnight
1831
+ */
1832
+ toStruct(value) {
1833
+ if (!value)
1834
+ return null;
1835
+ // Create UTC date at midnight to avoid timezone issues
1836
+ const utcDate = new Date(Date.UTC(value.getFullYear(), value.getMonth(), value.getDate()));
1837
+ return {
1838
+ year: utcDate.getUTCFullYear(),
1839
+ month: utcDate.getUTCMonth() + 1, // Convert from 0-11 to 1-12
1840
+ day: utcDate.getUTCDate(),
1841
+ };
1842
+ }
1843
+ /**
1844
+ * Converts internal struct to Date representation
1845
+ * Creates UTC Date at midnight (00:00:00)
1846
+ */
1847
+ fromStruct(struct) {
1848
+ if (!struct)
1849
+ return null;
1850
+ // Create UTC date at midnight (convert month from 1-12 to 0-11)
1851
+ return new Date(Date.UTC(struct.year, struct.month - 1, struct.day, 0, 0, 0, 0));
1852
+ }
1853
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerNativeUtcValueAdapter, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
1854
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerNativeUtcValueAdapter });
1855
+ }
1856
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerNativeUtcValueAdapter, decorators: [{
1857
+ type: Injectable
1858
+ }] });
1859
+
1860
+ class GaDatepickerNativeUtcIsoValueAdapter extends GaDatepickerValueAdapter {
1861
+ /**
1862
+ * Converts ISO Date to internal struct representation
1863
+ * Uses UTC to avoid timezone issues and normalizes to midnight
1864
+ */
1865
+ toStruct(value) {
1866
+ if (!value)
1867
+ return null;
1868
+ const date = new Date(value);
1869
+ if (isNaN(date.getTime())) {
1870
+ return null;
1871
+ }
1872
+ return {
1873
+ year: date.getUTCFullYear(),
1874
+ month: date.getUTCMonth() + 1,
1875
+ day: date.getUTCDate(),
1876
+ };
1877
+ }
1878
+ /**
1879
+ * Converts internal struct to ISO Date representation
1880
+ * Creates UTC Date at midnight (00:00:00)
1881
+ */
1882
+ fromStruct(struct) {
1883
+ if (!struct)
1884
+ return null;
1885
+ return new Date(Date.UTC(struct.year, struct.month - 1, struct.day, 0, 0, 0, 0)).toISOString();
1886
+ }
1887
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerNativeUtcIsoValueAdapter, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
1888
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerNativeUtcIsoValueAdapter });
1889
+ }
1890
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaDatepickerNativeUtcIsoValueAdapter, decorators: [{
1891
+ type: Injectable
1892
+ }] });
1893
+
805
1894
  class GaSegmentedControlComponent {
806
1895
  selected = model();
807
1896
  change = output();
@@ -929,87 +2018,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImpor
929
2018
  }]
930
2019
  }] });
931
2020
 
932
- class GaFormFieldConnector {
933
- controlDisabled = signal(false);
934
- controlId = signal(null);
935
- labelId = signal(null);
936
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFormFieldConnector, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
937
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFormFieldConnector });
938
- }
939
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaFormFieldConnector, decorators: [{
940
- type: Injectable
941
- }] });
942
-
943
- let nextUniqueId$7 = 0;
944
- class GaInputDirective {
945
- uniqueId = `ga-input-${++nextUniqueId$7}`;
946
- formFieldConnector = inject(GaFormFieldConnector, {
947
- optional: true,
948
- });
949
- hasWrapper = inject(GaInputComponent, { optional: true });
950
- implicitNgControlState = injectNgControlState();
951
- invalidInput = input(null, {
952
- alias: 'invalid',
953
- transform: booleanAttribute,
954
- });
955
- idInput = input(undefined, { alias: 'id' });
956
- disabledInput = input(undefined, {
957
- alias: 'disabled',
958
- transform: booleanAttribute,
959
- });
960
- invalid = computed(() => {
961
- return this.invalidInput() ?? this.implicitNgControlState.inError();
962
- });
963
- id = computed(() => {
964
- return this.idInput() ?? this.uniqueId;
965
- });
966
- disabled = computed(() => {
967
- return this.disabledInput() ?? this.implicitNgControlState.disabled();
968
- });
969
- constructor() {
970
- const formFieldConnector = this.formFieldConnector;
971
- if (formFieldConnector) {
972
- effect(() => formFieldConnector.controlDisabled.set(this.disabled()));
973
- effect(() => formFieldConnector.controlId.set(this.id()));
974
- }
975
- }
976
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaInputDirective, deps: [], target: i0.ɵɵFactoryTarget.Component });
977
- 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()", "attr.disabled": "disabled() ? \"\" : null" } }, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
978
- }
979
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaInputDirective, decorators: [{
980
- type: Component,
981
- args: [{
982
- // eslint-disable-next-line @angular-eslint/component-selector
983
- selector: '[gaInput]',
984
- template: '',
985
- changeDetection: ChangeDetectionStrategy.OnPush,
986
- host: {
987
- '[attr.id]': 'id()',
988
- '[class.ga-input]': '!hasWrapper',
989
- '[class.ga-input--invalid]': '!hasWrapper && invalid()',
990
- '[attr.disabled]': 'disabled() ? "" : null',
991
- },
992
- }]
993
- }], ctorParameters: () => [] });
994
-
995
- class GaInputComponent {
996
- gaInput = contentChild.required(GaInputDirective);
997
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
998
- 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 });
999
- }
1000
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaInputComponent, decorators: [{
1001
- type: Component,
1002
- args: [{
1003
- selector: 'ga-input',
1004
- template: `<ng-content />`,
1005
- changeDetection: ChangeDetectionStrategy.OnPush,
1006
- host: {
1007
- class: 'ga-input',
1008
- '[class.ga-input--invalid]': 'gaInput().invalid()',
1009
- },
1010
- }]
1011
- }] });
1012
-
1013
2021
  class GaInputModule {
1014
2022
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaInputModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1015
2023
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.0.4", ngImport: i0, type: GaInputModule, imports: [GaInputComponent, GaInputDirective], exports: [GaInputComponent, GaInputDirective] });
@@ -1678,7 +2686,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImpor
1678
2686
 
1679
2687
  class GaMenuComponent {
1680
2688
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1681
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.0.4", type: GaMenuComponent, isStandalone: true, selector: "ga-menu", host: { classAttribute: "ga-menu" }, hostDirectives: [{ directive: i1$1.CdkMenu }], ngImport: i0, template: `<ng-content />`, isInline: true, styles: [":host{margin-top:calc(var(--ga-size-spacing-03) * var(--ga-base-scaling-factor, 1));margin-bottom:calc(var(--ga-size-spacing-03) * var(--ga-base-scaling-factor, 1))}\n"] });
2689
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.0.4", type: GaMenuComponent, isStandalone: true, selector: "ga-menu", host: { classAttribute: "ga-menu" }, hostDirectives: [{ directive: i1$2.CdkMenu }], ngImport: i0, template: `<ng-content />`, isInline: true, styles: [":host{margin-top:calc(var(--ga-size-spacing-03) * var(--ga-base-scaling-factor, 1));margin-bottom:calc(var(--ga-size-spacing-03) * var(--ga-base-scaling-factor, 1))}\n"] });
1682
2690
  }
1683
2691
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaMenuComponent, decorators: [{
1684
2692
  type: Component,
@@ -1694,7 +2702,7 @@ class GaMenuItemComponent {
1694
2702
  description = input('', { alias: 'gaMenuItemDescription' });
1695
2703
  shortcut = input('', { alias: 'gaMenuItemShortcut' });
1696
2704
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaMenuItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1697
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.4", type: GaMenuItemComponent, isStandalone: true, selector: "[gaMenuItem]", inputs: { icon: { classPropertyName: "icon", publicName: "gaMenuItemIcon", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "gaMenuItemDescription", isSignal: true, isRequired: false, transformFunction: null }, shortcut: { classPropertyName: "shortcut", publicName: "gaMenuItemShortcut", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "ga-menu__item" }, hostDirectives: [{ directive: i1$1.CdkMenuItem }], ngImport: i0, template: "@if (icon()) {\n <ga-icon [icon]=\"icon()!\" class=\"ga-menu__item-icon\" size=\"16\" />\n}\n<div class=\"ga-menu__item-content\">\n <div class=\"ga-menu__item-title\">\n <div class=\"ga-menu__item-label\"><ng-content /></div>\n @if (shortcut()) {\n <span class=\"ga-menu__item-shortcut\">{{ shortcut() }}</span>\n }\n </div>\n @if (description()) {\n <div class=\"ga-menu__item-description\">{{ description() }}</div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: GaIconModule }, { kind: "component", type: GaIconComponent, selector: "ga-icon", inputs: ["icon", "size", "color", "strokeWidth"] }] });
2705
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.4", type: GaMenuItemComponent, isStandalone: true, selector: "[gaMenuItem]", inputs: { icon: { classPropertyName: "icon", publicName: "gaMenuItemIcon", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "gaMenuItemDescription", isSignal: true, isRequired: false, transformFunction: null }, shortcut: { classPropertyName: "shortcut", publicName: "gaMenuItemShortcut", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "ga-menu__item" }, hostDirectives: [{ directive: i1$2.CdkMenuItem }], ngImport: i0, template: "@if (icon()) {\n <ga-icon [icon]=\"icon()!\" class=\"ga-menu__item-icon\" size=\"16\" />\n}\n<div class=\"ga-menu__item-content\">\n <div class=\"ga-menu__item-title\">\n <div class=\"ga-menu__item-label\"><ng-content /></div>\n @if (shortcut()) {\n <span class=\"ga-menu__item-shortcut\">{{ shortcut() }}</span>\n }\n </div>\n @if (description()) {\n <div class=\"ga-menu__item-description\">{{ description() }}</div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: GaIconModule }, { kind: "component", type: GaIconComponent, selector: "ga-icon", inputs: ["icon", "size", "color", "strokeWidth"] }] });
1698
2706
  }
1699
2707
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaMenuItemComponent, decorators: [{
1700
2708
  type: Component,
@@ -1738,7 +2746,7 @@ class GaMenuTriggerDirective {
1738
2746
  return () => createRepositionScrollStrategy(injector);
1739
2747
  },
1740
2748
  },
1741
- ], exportAs: ["gaMenuTrigger"], hostDirectives: [{ directive: i1$1.CdkMenuTrigger, outputs: ["cdkMenuOpened", "gaMenuOpened", "cdkMenuClosed", "gaMenuClosed"] }], ngImport: i0 });
2749
+ ], exportAs: ["gaMenuTrigger"], hostDirectives: [{ directive: i1$2.CdkMenuTrigger, outputs: ["cdkMenuOpened", "gaMenuOpened", "cdkMenuClosed", "gaMenuClosed"] }], ngImport: i0 });
1742
2750
  }
1743
2751
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaMenuTriggerDirective, decorators: [{
1744
2752
  type: Directive,
@@ -2075,7 +3083,7 @@ class GaModalComponent {
2075
3083
  };
2076
3084
  }
2077
3085
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2078
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.0.4", type: GaModalComponent, isStandalone: true, selector: "ng-component", host: { properties: { "attr.role": "options.role", "attr.aria-labelledby": "options.labelledBy ?? labelledBy()", "attr.aria-describedby": "options.describedBy ?? describedBy()", "class.ga-modal--small": "options.size === 'sm'", "class.ga-modal--medium": "options.size === 'md'", "class.ga-modal--large": "options.size === 'lg'", "class.ga-modal--information": "options.type === 'info'", "class.ga-modal--danger": "options.type === 'danger'", "class.ga-modal--warning": "options.type === 'warning'", "class.ga-modal--success": "options.type === 'success'" }, classAttribute: "ga-modal" }, hostDirectives: [{ directive: i1$2.CdkTrapFocus }], ngImport: i0, template: '', isInline: true });
3086
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.0.4", type: GaModalComponent, isStandalone: true, selector: "ng-component", host: { properties: { "attr.role": "options.role", "attr.aria-labelledby": "options.labelledBy ?? labelledBy()", "attr.aria-describedby": "options.describedBy ?? describedBy()", "class.ga-modal--small": "options.size === 'sm'", "class.ga-modal--medium": "options.size === 'md'", "class.ga-modal--large": "options.size === 'lg'", "class.ga-modal--information": "options.type === 'info'", "class.ga-modal--danger": "options.type === 'danger'", "class.ga-modal--warning": "options.type === 'warning'", "class.ga-modal--success": "options.type === 'success'" }, classAttribute: "ga-modal" }, hostDirectives: [{ directive: i1$3.CdkTrapFocus }], ngImport: i0, template: '', isInline: true });
2079
3087
  }
2080
3088
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaModalComponent, decorators: [{
2081
3089
  type: Component,
@@ -2224,7 +3232,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImpor
2224
3232
 
2225
3233
  class GaModalContentComponent {
2226
3234
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaModalContentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2227
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.0.4", type: GaModalContentComponent, isStandalone: true, selector: "ga-modal-content", host: { classAttribute: "ga-modal__content" }, hostDirectives: [{ directive: i1$3.CdkScrollable }], ngImport: i0, template: `<ng-content />`, isInline: true });
3235
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.0.4", type: GaModalContentComponent, isStandalone: true, selector: "ga-modal-content", host: { classAttribute: "ga-modal__content" }, hostDirectives: [{ directive: i1$4.CdkScrollable }], ngImport: i0, template: `<ng-content />`, isInline: true });
2228
3236
  }
2229
3237
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaModalContentComponent, decorators: [{
2230
3238
  type: Component,
@@ -2631,7 +3639,7 @@ class GaOptionComponent {
2631
3639
  }
2632
3640
  }
2633
3641
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaOptionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2634
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.4", type: GaOptionComponent, isStandalone: true, selector: "ga-option", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, hidden: { classPropertyName: "hidden", publicName: "hidden", isSignal: true, isRequired: false, transformFunction: null }, withInput: { classPropertyName: "withInput", publicName: "withInput", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "onClick()" }, properties: { "class.ga-dropdown__item--selected": "selected()", "class.ga-dropdown__item--disabled": "cdkOption.disabled", "class.ga-dropdown__item--active": "active() && !cdkOption.disabled", "attr.hidden": "hidden() ? '' : null" }, classAttribute: "ga-dropdown__item" }, hostDirectives: [{ directive: i1$4.CdkOption, inputs: ["cdkOption", "value", "cdkOptionDisabled", "disabled", "cdkOptionTypeaheadLabel", "typeaheadLabel"] }], ngImport: i0, template: "@if (withInput()) {\n @if (selectComponent.multiple()) {\n <ga-checkbox\n [checked]=\"selected()\"\n [disabled]=\"disabled()\"\n aria-hidden=\"true\"\n style=\"pointer-events: none\"\n tabindex=\"-1\"\n />\n } @else {\n <ga-radio-button\n [checked]=\"selected()\"\n [disabled]=\"disabled()\"\n aria-hidden=\"true\"\n style=\"pointer-events: none\"\n tabindex=\"-1\"\n />\n }\n}\n<div class=\"ga-dropdown__item-label\"><ng-content /></div>\n", dependencies: [{ kind: "ngmodule", type: GaCheckboxModule }, { kind: "component", type: GaCheckboxComponent, selector: "ga-checkbox", inputs: ["value", "disabled", "checked", "name", "id", "indeterminate", "aria-label", "aria-labelledby", "aria-describedby", "aria-invalid", "aria-errormessage", "required"], outputs: ["change", "indeterminateChange"] }, { kind: "ngmodule", type: GaRadioModule }, { kind: "component", type: GaRadioButtonComponent, selector: "ga-radio-button", inputs: ["value", "id", "name", "checked", "disabled", "aria-label", "aria-labelledby", "aria-describedby", "aria-invalid", "aria-errormessage"], outputs: ["change"] }] });
3642
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.4", type: GaOptionComponent, isStandalone: true, selector: "ga-option", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, hidden: { classPropertyName: "hidden", publicName: "hidden", isSignal: true, isRequired: false, transformFunction: null }, withInput: { classPropertyName: "withInput", publicName: "withInput", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "onClick()" }, properties: { "class.ga-dropdown__item--selected": "selected()", "class.ga-dropdown__item--disabled": "cdkOption.disabled", "class.ga-dropdown__item--active": "active() && !cdkOption.disabled", "attr.hidden": "hidden() ? '' : null" }, classAttribute: "ga-dropdown__item" }, hostDirectives: [{ directive: i1$5.CdkOption, inputs: ["cdkOption", "value", "cdkOptionDisabled", "disabled", "cdkOptionTypeaheadLabel", "typeaheadLabel"] }], ngImport: i0, template: "@if (withInput()) {\n @if (selectComponent.multiple()) {\n <ga-checkbox\n [checked]=\"selected()\"\n [disabled]=\"disabled()\"\n aria-hidden=\"true\"\n style=\"pointer-events: none\"\n tabindex=\"-1\"\n />\n } @else {\n <ga-radio-button\n [checked]=\"selected()\"\n [disabled]=\"disabled()\"\n aria-hidden=\"true\"\n style=\"pointer-events: none\"\n tabindex=\"-1\"\n />\n }\n}\n<div class=\"ga-dropdown__item-label\"><ng-content /></div>\n", dependencies: [{ kind: "ngmodule", type: GaCheckboxModule }, { kind: "component", type: GaCheckboxComponent, selector: "ga-checkbox", inputs: ["value", "disabled", "checked", "name", "id", "indeterminate", "aria-label", "aria-labelledby", "aria-describedby", "aria-invalid", "aria-errormessage", "required"], outputs: ["change", "indeterminateChange"] }, { kind: "ngmodule", type: GaRadioModule }, { kind: "component", type: GaRadioButtonComponent, selector: "ga-radio-button", inputs: ["value", "id", "name", "checked", "disabled", "aria-label", "aria-labelledby", "aria-describedby", "aria-invalid", "aria-errormessage"], outputs: ["change"] }] });
2635
3643
  }
2636
3644
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaOptionComponent, decorators: [{
2637
3645
  type: Component,
@@ -2799,6 +3807,7 @@ class GaSelectComponent {
2799
3807
  customSelectValue = contentChild(GaSelectValueComponent);
2800
3808
  inputSearch = viewChild('inputSearch');
2801
3809
  content = viewChild('ngContent', { read: ElementRef });
3810
+ connectedOverlay = viewChild(CdkConnectedOverlay);
2802
3811
  id = computed(() => {
2803
3812
  return this.idInput() ?? this._uniqueId;
2804
3813
  });
@@ -2838,6 +3847,10 @@ class GaSelectComponent {
2838
3847
  if (formFieldConnector) {
2839
3848
  effect(() => formFieldConnector.controlDisabled.set(this.disabled()));
2840
3849
  }
3850
+ effect(() => {
3851
+ this.gaOptions(); // explicit call to track the option changes
3852
+ untracked(() => this.connectedOverlay()?.overlayRef?.updatePosition());
3853
+ });
2841
3854
  }
2842
3855
  ngAfterContentInit() {
2843
3856
  effect(() => {
@@ -3029,7 +4042,7 @@ class GaSelectComponent {
3029
4042
  useExisting: forwardRef(() => GaSelectComponent),
3030
4043
  multi: true,
3031
4044
  },
3032
- ], 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" }] });
4045
+ ], 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 }, { propertyName: "connectedOverlay", first: true, predicate: CdkConnectedOverlay, descendants: true, isSignal: true }], hostDirectives: [{ directive: i1$1.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 [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$1.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" }] });
3033
4046
  }
3034
4047
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaSelectComponent, decorators: [{
3035
4048
  type: Component,
@@ -3072,7 +4085,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImpor
3072
4085
  '(keydown.space)': 'open(); $event.preventDefault()',
3073
4086
  '(keydown.enter)': 'open(); $event.preventDefault()',
3074
4087
  '(keydown.backspace)': 'clearValue(); $event.preventDefault()',
3075
- }, 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" }]
4088
+ }, 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 [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" }]
3076
4089
  }], ctorParameters: () => [] });
3077
4090
 
3078
4091
  class GaOptgroupComponent {
@@ -3133,7 +4146,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImpor
3133
4146
  class GaSelectDropdownComponent {
3134
4147
  loading = input(false, { transform: booleanAttribute });
3135
4148
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaSelectDropdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3136
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.4", type: GaSelectDropdownComponent, isStandalone: true, selector: "ga-select-dropdown", inputs: { loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "ga-dropdown ga-dropdown__content" }, hostDirectives: [{ directive: i1$4.CdkListbox }], ngImport: i0, template: "@if (loading()) {\n <ga-select-dropdown-spinner />\n} @else {\n <ng-content />\n}\n", dependencies: [{ kind: "component", type: GaSelectDropdownSpinnerComponent, selector: "ga-select-dropdown-spinner" }] });
4149
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.4", type: GaSelectDropdownComponent, isStandalone: true, selector: "ga-select-dropdown", inputs: { loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "ga-dropdown ga-dropdown__content" }, hostDirectives: [{ directive: i1$5.CdkListbox }], ngImport: i0, template: "@if (loading()) {\n <ga-select-dropdown-spinner />\n} @else {\n <ng-content />\n}\n", dependencies: [{ kind: "component", type: GaSelectDropdownSpinnerComponent, selector: "ga-select-dropdown-spinner" }] });
3137
4150
  }
3138
4151
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaSelectDropdownComponent, decorators: [{
3139
4152
  type: Component,
@@ -3412,6 +4425,8 @@ class GaTextAreaDirective {
3412
4425
  formFieldConnector = inject(GaFormFieldConnector, {
3413
4426
  optional: true,
3414
4427
  });
4428
+ renderer = inject(Renderer2);
4429
+ elementRef = inject(ElementRef);
3415
4430
  uniqueId = `ga-text-area-${++nextUniqueId}`;
3416
4431
  idInput = input(undefined, { alias: 'id' });
3417
4432
  disabledInput = input(false, {
@@ -3425,14 +4440,18 @@ class GaTextAreaDirective {
3425
4440
  disabled = computed(() => this.disabledInput() ?? this.implicitNgControlState.disabled());
3426
4441
  invalid = computed(() => this.invalidInput() ?? this.implicitNgControlState.inError());
3427
4442
  id = computed(() => this.idInput() ?? this.uniqueId);
3428
- constructor() {
4443
+ constructor(placeholder) {
3429
4444
  const formFieldConnector = this.formFieldConnector;
3430
4445
  if (formFieldConnector) {
3431
4446
  effect(() => formFieldConnector.controlDisabled.set(this.disabled()));
3432
4447
  effect(() => formFieldConnector.controlId.set(this.id()));
3433
4448
  }
4449
+ if (!placeholder) {
4450
+ // a workaround till https://github.com/visma-software-nordic/gaia-styles/issues/108 is fixed
4451
+ this.renderer.setAttribute(this.elementRef.nativeElement, 'placeholder', '');
4452
+ }
3434
4453
  }
3435
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaTextAreaDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
4454
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaTextAreaDirective, deps: [{ token: 'placeholder', attribute: true }], target: i0.ɵɵFactoryTarget.Directive });
3436
4455
  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()", "attr.disabled": "disabled() ? true : null" }, classAttribute: "ga-text-area" }, ngImport: i0 });
3437
4456
  }
3438
4457
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaTextAreaDirective, decorators: [{
@@ -3446,7 +4465,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImpor
3446
4465
  '[attr.disabled]': 'disabled() ? true : null',
3447
4466
  },
3448
4467
  }]
3449
- }], ctorParameters: () => [] });
4468
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
4469
+ type: Attribute,
4470
+ args: ['placeholder']
4471
+ }] }] });
3450
4472
 
3451
4473
  class GaTextAreaModule {
3452
4474
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: GaTextAreaModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
@@ -3469,5 +4491,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImpor
3469
4491
  * Generated bundle index. Do not edit.
3470
4492
  */
3471
4493
 
3472
- 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 };
4494
+ 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_DATEPICKER_I18N_FACTORY, GA_DATEPICKER_PARSER_FORMATTER_FACTORY, GA_DATEPICKER_VALUE_ADAPTER_FACTORY, GA_DATE_PARSER_FORMATTER_CONFIG, GA_DEFAULT_DATEPICKER_FORMATS, 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, GaDatepickerComponent, GaDatepickerI18n, GaDatepickerI18nDefault, GaDatepickerInputDirective, GaDatepickerModule, GaDatepickerNativeUtcIsoValueAdapter, GaDatepickerNativeUtcValueAdapter, GaDatepickerParserFormatter, GaDatepickerParserFormatterDefault, GaDatepickerStructValueAdapter, GaDatepickerToggleComponent, GaDatepickerValueAdapter, 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, compareStructs, extendGaDateParserFormatter, injectNgControlState, provideGaAlertI18n, provideGaBaseFontSize, provideGaButtonI18n, provideGaDatepickerI18n, provideGaDatepickerParserFormatter, provideGaDatepickerValueAdapter, provideGaModalI18n, provideGaModalOptions, provideGaSelectI18n };
3473
4495
  //# sourceMappingURL=vsn-ux-ngx-gaia.mjs.map