@vsn-ux/ngx-gaia 0.12.0 → 0.12.2

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.
@@ -24,6 +24,7 @@ Input directive for datepicker integration. Implements ControlValueAccessor and
24
24
  - `disabled: boolean` - Disabled state (default: false)
25
25
  - `min: any` - Minimum date constraint (default: null)
26
26
  - `max: any` - Maximum date constraint (default: null)
27
+ - `preserveRawValue: boolean` - Push raw string to model on invalid input instead of null; useful with signal forms where schema-based validators need to distinguish empty fields from format errors (default: false)
27
28
 
28
29
  ### Outputs
29
30
 
@@ -111,6 +112,7 @@ interface GaDatepickerStruct {
111
112
  - `provideGaDatepickerI18n(value)` - Configure i18n (accepts class, object, or factory)
112
113
  - `provideGaDatepickerParserFormatter(value)` - Configure parser/formatter (accepts class or factory)
113
114
  - `provideGaDatepickerValueAdapter<T>(value)` - Configure value adapter (accepts class)
115
+ - `provideGaDatepickerInputOptions(options)` - Configure datepicker input options globally (e.g. `{ preserveRawValue: true }`)
114
116
  - `extendGaDateParserFormatter(formats)` - Extend default date formats for additional locales
115
117
 
116
118
  ## Examples
@@ -146,6 +148,17 @@ Using native Date adapter:
146
148
  providers: [provideGaDatepickerValueAdapter(GaDatepickerNativeUtcValueAdapter)];
147
149
  ```
148
150
 
151
+ Preserve raw value for signal forms validation:
152
+
153
+ ```html
154
+ <input gaInput gaDatepickerInput [(ngModel)]="date" preserveRawValue />
155
+ ```
156
+
157
+ ```typescript
158
+ // Or enable globally
159
+ providers: [provideGaDatepickerInputOptions({ preserveRawValue: true })];
160
+ ```
161
+
149
162
  Custom i18n labels:
150
163
 
151
164
  ```typescript
@@ -1677,10 +1677,28 @@ function provideGaDatepickerParserFormatter(value) {
1677
1677
  : { provide: GaDatepickerParserFormatter, useValue: value };
1678
1678
  }
1679
1679
 
1680
+ const GA_DEFAULT_DATEPICKER_INPUT_OPTIONS = {
1681
+ preserveRawValue: false,
1682
+ };
1683
+ const GA_DATEPICKER_INPUT_OPTIONS = new InjectionToken('GA_DATEPICKER_INPUT_OPTIONS', {
1684
+ providedIn: 'root',
1685
+ factory: () => GA_DEFAULT_DATEPICKER_INPUT_OPTIONS,
1686
+ });
1687
+ function provideGaDatepickerInputOptions(options) {
1688
+ return {
1689
+ provide: GA_DATEPICKER_INPUT_OPTIONS,
1690
+ useValue: { ...GA_DEFAULT_DATEPICKER_INPUT_OPTIONS, ...options },
1691
+ };
1692
+ }
1693
+
1680
1694
  class GaDatepickerInputDirective {
1681
1695
  inputElRef = inject(ElementRef, { self: true });
1682
1696
  parserFormatter = inject(GaDatepickerParserFormatter);
1683
1697
  valueAdapter = inject(GaDatepickerValueAdapter);
1698
+ globalOptions = inject(GA_DATEPICKER_INPUT_OPTIONS);
1699
+ preserveRawValueInput = input(undefined, { ...(ngDevMode ? { debugName: "preserveRawValueInput" } : {}), alias: 'preserveRawValue',
1700
+ transform: booleanAttribute });
1701
+ preserveRawValue = computed(() => this.preserveRawValueInput() ?? this.globalOptions.preserveRawValue, ...(ngDevMode ? [{ debugName: "preserveRawValue" }] : []));
1684
1702
  // Native value control (alternative to Angular forms)
1685
1703
  valueInput = input(null, { ...(ngDevMode ? { debugName: "valueInput" } : {}), alias: 'value' });
1686
1704
  disabledInput = input(null, { ...(ngDevMode ? { debugName: "disabledInput" } : {}), alias: 'disabled',
@@ -1694,6 +1712,7 @@ class GaDatepickerInputDirective {
1694
1712
  disabled = linkedSignal(() => !!this.disabledInput(), ...(ngDevMode ? [{ debugName: "disabled" }] : []));
1695
1713
  lastValueValid = signal(false, ...(ngDevMode ? [{ debugName: "lastValueValid" }] : []));
1696
1714
  lastDateChangeEmittedValue = signal(null, ...(ngDevMode ? [{ debugName: "lastDateChangeEmittedValue" }] : []));
1715
+ focused = false;
1697
1716
  onNgChangeFn;
1698
1717
  onNgTouchedFn;
1699
1718
  constructor() {
@@ -1706,20 +1725,33 @@ class GaDatepickerInputDirective {
1706
1725
  });
1707
1726
  });
1708
1727
  }
1728
+ onFocus() {
1729
+ this.focused = true;
1730
+ }
1709
1731
  onInput(event) {
1710
1732
  const target = event.target;
1711
1733
  // Parse the input value
1712
1734
  const parsedStruct = this.parserFormatter.parse(target.value);
1713
- const newValue = this.valueAdapter.fromStruct(parsedStruct);
1714
- this.lastValueValid.set(!target.value || parsedStruct !== null);
1715
- // Only update if the parsed value is different from current value
1716
- if (compareStructs(parsedStruct, this.dateStruct()) !== 0) {
1717
- this.value.set(newValue);
1718
- this.dateInput.emit(newValue);
1735
+ const isValid = !target.value || parsedStruct !== null;
1736
+ this.lastValueValid.set(isValid);
1737
+ if (isValid || !this.preserveRawValue()) {
1738
+ // Existing behavior: convert struct to external value
1739
+ const newValue = this.valueAdapter.fromStruct(parsedStruct);
1740
+ if (compareStructs(parsedStruct, this.dateStruct()) !== 0) {
1741
+ this.value.set(newValue);
1742
+ this.dateInput.emit(newValue);
1743
+ }
1744
+ this.onNgChangeFn?.(newValue);
1745
+ }
1746
+ else {
1747
+ // preserveRawValue ON + invalid input: push raw string
1748
+ this.value.set(target.value);
1749
+ this.dateInput.emit(target.value);
1750
+ this.onNgChangeFn?.(target.value);
1719
1751
  }
1720
- this.onNgChangeFn?.(newValue);
1721
1752
  }
1722
1753
  onBlur() {
1754
+ this.focused = false;
1723
1755
  if (this.dateStruct()) {
1724
1756
  this.formatValue();
1725
1757
  }
@@ -1730,9 +1762,16 @@ class GaDatepickerInputDirective {
1730
1762
  this.onNgTouchedFn?.();
1731
1763
  }
1732
1764
  formatValue() {
1733
- const value = this.dateStruct();
1734
- const formattedValue = this.parserFormatter.format(value);
1735
- this.inputElRef.nativeElement.value = formattedValue;
1765
+ const struct = this.dateStruct();
1766
+ if (struct) {
1767
+ this.inputElRef.nativeElement.value = this.parserFormatter.format(struct);
1768
+ }
1769
+ else if (this.preserveRawValue() && typeof this.value() === 'string') {
1770
+ this.inputElRef.nativeElement.value = this.value();
1771
+ }
1772
+ else {
1773
+ this.inputElRef.nativeElement.value = this.parserFormatter.format(null);
1774
+ }
1736
1775
  }
1737
1776
  updateValue(value, { updateView, emitToNgModel, } = {}) {
1738
1777
  this.value.set(value);
@@ -1751,7 +1790,7 @@ class GaDatepickerInputDirective {
1751
1790
  }
1752
1791
  // ControlValueAccessor implementation
1753
1792
  writeValue(value) {
1754
- this.updateValue(value, { updateView: true });
1793
+ this.updateValue(value, { updateView: !this.focused });
1755
1794
  }
1756
1795
  registerOnChange(fn) {
1757
1796
  this.onNgChangeFn = fn;
@@ -1786,7 +1825,7 @@ class GaDatepickerInputDirective {
1786
1825
  return null;
1787
1826
  }
1788
1827
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: GaDatepickerInputDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1789
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.0", 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: [
1828
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.0", type: GaDatepickerInputDirective, isStandalone: true, selector: "input[gaDatepickerInput]", inputs: { preserveRawValueInput: { classPropertyName: "preserveRawValueInput", publicName: "preserveRawValue", isSignal: true, isRequired: false, transformFunction: null }, 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: { "focus": "onFocus()", "blur": "onBlur()", "input": "onInput($event)" }, properties: { "disabled": "disabled()" } }, providers: [
1790
1829
  {
1791
1830
  provide: NG_VALUE_ACCESSOR,
1792
1831
  useExisting: forwardRef(() => GaDatepickerInputDirective),
@@ -1818,11 +1857,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
1818
1857
  ],
1819
1858
  host: {
1820
1859
  '[disabled]': 'disabled()',
1860
+ '(focus)': 'onFocus()',
1821
1861
  '(blur)': 'onBlur()',
1822
1862
  '(input)': 'onInput($event)',
1823
1863
  },
1824
1864
  }]
1825
- }], ctorParameters: () => [], propDecorators: { valueInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], dateInput: [{ type: i0.Output, args: ["dateInput"] }], dateChange: [{ type: i0.Output, args: ["dateChange"] }] } });
1865
+ }], ctorParameters: () => [], propDecorators: { preserveRawValueInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "preserveRawValue", required: false }] }], valueInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], dateInput: [{ type: i0.Output, args: ["dateInput"] }], dateChange: [{ type: i0.Output, args: ["dateChange"] }] } });
1826
1866
 
1827
1867
  class GaDatepickerModule {
1828
1868
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: GaDatepickerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
@@ -1856,7 +1896,7 @@ class GaDatepickerNativeUtcValueAdapter extends GaDatepickerValueAdapter {
1856
1896
  * Uses UTC to avoid timezone issues and normalizes to midnight
1857
1897
  */
1858
1898
  toStruct(value) {
1859
- if (!value)
1899
+ if (!value || !(value instanceof Date))
1860
1900
  return null;
1861
1901
  // Create UTC date at midnight to avoid timezone issues
1862
1902
  const utcDate = new Date(Date.UTC(value.getFullYear(), value.getMonth(), value.getDate()));
@@ -6492,5 +6532,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
6492
6532
  * Generated bundle index. Do not edit.
6493
6533
  */
6494
6534
 
6495
- 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_DATA_SELECT_I18N_FACTORY, GA_DATA_SELECT_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_DEFAULT_TOAST_OPTIONS, GA_FORM_CONTROL_ADAPTER, GA_FORM_ERRORS, GA_ICON_DEFAULT_SIZE, GA_MODAL_DATA, GA_MODAL_I18N_FACTORY, GA_SELECT_I18N_FACTORY, GA_SELECT_REQUIRED_VALIDATOR, GA_TABS_I18N_FACTORY, GA_TOAST_OPTIONS, GA_TOOLTIP_DEFAULT_OFFSET, GaAlertComponent, GaAlertI18n, GaAlertI18nDefault, GaAlertModule, GaAlertTitleActionsComponent, GaAlertTitleComponent, GaBadgeComponent, GaBadgeModule, GaButtonDirective, GaButtonI18n, GaButtonI18nDefault, GaButtonModule, GaCardComponent, GaCardModule, GaCheckboxComponent, GaCheckboxModule, GaCheckboxRequiredValidator, GaChipComponent, GaChipListboxComponent, GaChipModule, GaDataSelectComponent, GaDataSelectI18n, GaDataSelectI18nDefault, GaDataSelectModule, GaDataSelectOptgroupLabelDirective, GaDataSelectOptionLabelDirective, GaDataSelectRequiredValidator, GaDataSelectValueDirective, 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, GaStepComponent, GaStepperComponent, GaStepperModule, GaStepperPanelDirective, GaSwitchComponent, GaSwitchModule, GaTabComponent, GaTabContentDirective, GaTabsComponent, GaTabsI18n, GaTabsI18nDefault, GaTabsModule, GaTextAreaDirective, GaTextAreaModule, GaToastComponent, GaToaster, GaTooltipComponent, GaTooltipDirective, GaTooltipModule, GaTooltipTitleComponent, RADIO_CONTROL_VALUE_ACCESSOR, SWITCH_CONTROL_VALUE_ACCESSOR, compareStructs, extendGaDateParserFormatter, injectNgControlState, provideGaAlertI18n, provideGaBaseFontSize, provideGaButtonI18n, provideGaDataSelectI18n, provideGaDatepickerI18n, provideGaDatepickerParserFormatter, provideGaDatepickerValueAdapter, provideGaFormErrors, provideGaModalI18n, provideGaModalOptions, provideGaSelectI18n, provideGaTabsI18n, provideGaToastOptions };
6535
+ 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_DATA_SELECT_I18N_FACTORY, GA_DATA_SELECT_REQUIRED_VALIDATOR, GA_DATEPICKER_I18N_FACTORY, GA_DATEPICKER_INPUT_OPTIONS, GA_DATEPICKER_PARSER_FORMATTER_FACTORY, GA_DATEPICKER_VALUE_ADAPTER_FACTORY, GA_DATE_PARSER_FORMATTER_CONFIG, GA_DEFAULT_DATEPICKER_FORMATS, GA_DEFAULT_DATEPICKER_INPUT_OPTIONS, GA_DEFAULT_TOAST_OPTIONS, GA_FORM_CONTROL_ADAPTER, GA_FORM_ERRORS, GA_ICON_DEFAULT_SIZE, GA_MODAL_DATA, GA_MODAL_I18N_FACTORY, GA_SELECT_I18N_FACTORY, GA_SELECT_REQUIRED_VALIDATOR, GA_TABS_I18N_FACTORY, GA_TOAST_OPTIONS, GA_TOOLTIP_DEFAULT_OFFSET, GaAlertComponent, GaAlertI18n, GaAlertI18nDefault, GaAlertModule, GaAlertTitleActionsComponent, GaAlertTitleComponent, GaBadgeComponent, GaBadgeModule, GaButtonDirective, GaButtonI18n, GaButtonI18nDefault, GaButtonModule, GaCardComponent, GaCardModule, GaCheckboxComponent, GaCheckboxModule, GaCheckboxRequiredValidator, GaChipComponent, GaChipListboxComponent, GaChipModule, GaDataSelectComponent, GaDataSelectI18n, GaDataSelectI18nDefault, GaDataSelectModule, GaDataSelectOptgroupLabelDirective, GaDataSelectOptionLabelDirective, GaDataSelectRequiredValidator, GaDataSelectValueDirective, 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, GaStepComponent, GaStepperComponent, GaStepperModule, GaStepperPanelDirective, GaSwitchComponent, GaSwitchModule, GaTabComponent, GaTabContentDirective, GaTabsComponent, GaTabsI18n, GaTabsI18nDefault, GaTabsModule, GaTextAreaDirective, GaTextAreaModule, GaToastComponent, GaToaster, GaTooltipComponent, GaTooltipDirective, GaTooltipModule, GaTooltipTitleComponent, RADIO_CONTROL_VALUE_ACCESSOR, SWITCH_CONTROL_VALUE_ACCESSOR, compareStructs, extendGaDateParserFormatter, injectNgControlState, provideGaAlertI18n, provideGaBaseFontSize, provideGaButtonI18n, provideGaDataSelectI18n, provideGaDatepickerI18n, provideGaDatepickerInputOptions, provideGaDatepickerParserFormatter, provideGaDatepickerValueAdapter, provideGaFormErrors, provideGaModalI18n, provideGaModalOptions, provideGaSelectI18n, provideGaTabsI18n, provideGaToastOptions };
6496
6536
  //# sourceMappingURL=vsn-ux-ngx-gaia.mjs.map