@cocoar/ui-components 0.1.0-beta.115 → 0.1.0-beta.118

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.
@@ -7,6 +7,8 @@ import { shareReplay, catchError, finalize } from 'rxjs/operators';
7
7
  import { HttpClient } from '@angular/common/http';
8
8
  import { Maskito } from '@maskito/core';
9
9
  import { maskitoNumberOptionsGenerator, maskitoDateOptionsGenerator } from '@maskito/kit';
10
+ import { toSignal, takeUntilDestroyed } from '@angular/core/rxjs-interop';
11
+ import { CoarLocalizationService, CoarLocalizationDataStore } from '@cocoar/localization';
10
12
  import { OverlayScrollbars, ClickScrollPlugin } from 'overlayscrollbars';
11
13
  import { createOverlayBuilder } from '@cocoar/ui-overlay';
12
14
  import * as i1 from '@angular/common';
@@ -19,7 +21,6 @@ import 'prismjs/components/prism-scss';
19
21
  import 'prismjs/components/prism-json';
20
22
  import 'prismjs/components/prism-bash';
21
23
  import 'prismjs/components/prism-markup';
22
- import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
23
24
  import { Temporal } from '@js-temporal/polyfill';
24
25
 
25
26
  const COAR_ICON_SOURCE_ENTRY = new InjectionToken('COAR_ICON_SOURCE_ENTRY');
@@ -641,6 +642,8 @@ function transformStepperButtons(value) {
641
642
  }
642
643
  class CoarNumberInputComponent extends CoarControlValueAccessor {
643
644
  destroyRef = inject(DestroyRef);
645
+ localizationService = inject(CoarLocalizationService, { optional: true });
646
+ currentLanguage = toSignal(this.localizationService?.languageChanged$ ?? of(navigator.language));
644
647
  maskitoInstance;
645
648
  /** Label text displayed above the input */
646
649
  label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
@@ -792,7 +795,7 @@ class CoarNumberInputComponent extends CoarControlValueAccessor {
792
795
  return format;
793
796
  }
794
797
  // Priority 2: Use Intl.NumberFormat to detect format for the locale
795
- const locale = this.locale();
798
+ const locale = this.locale() ?? this.currentLanguage() ?? navigator.language;
796
799
  if (locale) {
797
800
  try {
798
801
  const formatter = new Intl.NumberFormat(locale);
@@ -4029,7 +4032,11 @@ class CoarDatePickerComponent extends CoarControlValueAccessor {
4029
4032
  elementRef = inject(ElementRef);
4030
4033
  destroyRef = inject(DestroyRef);
4031
4034
  overlayBuilder = createOverlayBuilder();
4035
+ localizationService = inject(CoarLocalizationService, { optional: true });
4036
+ localizationDataStore = inject(CoarLocalizationDataStore, { optional: true });
4032
4037
  overlayRef = null;
4038
+ /** Current language from localization service (reactive) */
4039
+ currentLanguage = toSignal(this.localizationService?.languageChanged$ ?? of(navigator.language));
4033
4040
  // ============================================================
4034
4041
  // Inputs
4035
4042
  // ============================================================
@@ -4142,7 +4149,7 @@ class CoarDatePickerComponent extends CoarControlValueAccessor {
4142
4149
  // ============================================================
4143
4150
  /**
4144
4151
  * Effective date format configuration.
4145
- * Priority: input dateFormatConfig > browser Intl detection > fallback
4152
+ * Priority: input dateFormatConfig > localization service > browser Intl detection > fallback
4146
4153
  */
4147
4154
  effectiveDateFormat = computed(() => {
4148
4155
  // 1. Direct config input takes highest priority
@@ -4150,8 +4157,19 @@ class CoarDatePickerComponent extends CoarControlValueAccessor {
4150
4157
  if (directConfig) {
4151
4158
  return directConfig;
4152
4159
  }
4153
- // 2. Detect from browser Intl (lightweight fallback)
4154
- const locale = this.locale() ?? navigator.language;
4160
+ // 2. Try to get from localization data store (which uses Intl with proper firstDayOfWeek detection)
4161
+ const currentLang = this.localizationService?.getCurrentLanguage();
4162
+ const localeData = currentLang
4163
+ ? this.localizationDataStore?.getLocaleData(currentLang)
4164
+ : undefined;
4165
+ if (localeData?.date) {
4166
+ return {
4167
+ pattern: localeData.date.pattern,
4168
+ firstDayOfWeek: localeData.date.firstDayOfWeek === 0 ? 7 : 1, // Convert 0=Sunday to 7, keep 1=Monday
4169
+ };
4170
+ }
4171
+ // 3. Fallback to Intl detection (for components without localization service)
4172
+ const locale = this.effectiveLocale();
4155
4173
  try {
4156
4174
  const formatter = new Intl.DateTimeFormat(locale);
4157
4175
  const parts = formatter.formatToParts(new Date(2024, 0, 15));
@@ -4168,7 +4186,7 @@ class CoarDatePickerComponent extends CoarControlValueAccessor {
4168
4186
  return { pattern, firstDayOfWeek: 1 };
4169
4187
  }
4170
4188
  catch {
4171
- // 3. Fallback
4189
+ // 4. Final fallback
4172
4190
  return { pattern: 'dd.mm.yyyy', firstDayOfWeek: 1 };
4173
4191
  }
4174
4192
  }, ...(ngDevMode ? [{ debugName: "effectiveDateFormat" }] : []));
@@ -4191,10 +4209,10 @@ class CoarDatePickerComponent extends CoarControlValueAccessor {
4191
4209
  }, ...(ngDevMode ? [{ debugName: "inputPlaceholder" }] : []));
4192
4210
  /**
4193
4211
  * Effective locale for calendar month/year display.
4194
- * Priority: input locale > locale service default > browser locale
4212
+ * Priority: input locale > locale service language > browser locale
4195
4213
  */
4196
4214
  effectiveLocale = computed(() => {
4197
- return this.locale() ?? navigator.language;
4215
+ return this.locale() ?? this.currentLanguage() ?? navigator.language;
4198
4216
  }, ...(ngDevMode ? [{ debugName: "effectiveLocale" }] : []));
4199
4217
  /** Whether the picker has an error state */
4200
4218
  hasError = computed(() => this.error(), ...(ngDevMode ? [{ debugName: "hasError" }] : []));
@@ -4324,7 +4342,12 @@ class CoarDatePickerComponent extends CoarControlValueAccessor {
4324
4342
  this.calendarPosition.set(placement === 'top' ? 'top' : 'bottom');
4325
4343
  const ref = this.overlayBuilder
4326
4344
  .anchor({ kind: 'element', element: trigger })
4327
- .position({ placement, offset: 4, flip: false, shift: false })
4345
+ .position({
4346
+ placement: placement === 'top' ? 'top-end' : 'bottom-end',
4347
+ offset: 4,
4348
+ flip: false,
4349
+ shift: false,
4350
+ })
4328
4351
  .scroll({ strategy: 'reposition' })
4329
4352
  .dismiss({ outsideClick: true, escapeKey: true })
4330
4353
  .size({ mode: 'content' })