@radix-ng/primitives 1.0.10 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +26 -5
  2. package/fesm2022/radix-ng-primitives-autocomplete.mjs +24 -16
  3. package/fesm2022/radix-ng-primitives-autocomplete.mjs.map +1 -1
  4. package/fesm2022/radix-ng-primitives-checkbox.mjs +55 -7
  5. package/fesm2022/radix-ng-primitives-checkbox.mjs.map +1 -1
  6. package/fesm2022/radix-ng-primitives-combobox.mjs +35 -18
  7. package/fesm2022/radix-ng-primitives-combobox.mjs.map +1 -1
  8. package/fesm2022/radix-ng-primitives-composite.mjs +221 -36
  9. package/fesm2022/radix-ng-primitives-composite.mjs.map +1 -1
  10. package/fesm2022/radix-ng-primitives-core.mjs +181 -21
  11. package/fesm2022/radix-ng-primitives-core.mjs.map +1 -1
  12. package/fesm2022/radix-ng-primitives-date-field.mjs +11 -5
  13. package/fesm2022/radix-ng-primitives-date-field.mjs.map +1 -1
  14. package/fesm2022/radix-ng-primitives-field.mjs +127 -23
  15. package/fesm2022/radix-ng-primitives-field.mjs.map +1 -1
  16. package/fesm2022/radix-ng-primitives-form.mjs +35 -4
  17. package/fesm2022/radix-ng-primitives-form.mjs.map +1 -1
  18. package/fesm2022/radix-ng-primitives-input.mjs +87 -15
  19. package/fesm2022/radix-ng-primitives-input.mjs.map +1 -1
  20. package/fesm2022/radix-ng-primitives-menu.mjs +34 -7
  21. package/fesm2022/radix-ng-primitives-menu.mjs.map +1 -1
  22. package/fesm2022/radix-ng-primitives-popper.mjs +80 -11
  23. package/fesm2022/radix-ng-primitives-popper.mjs.map +1 -1
  24. package/fesm2022/radix-ng-primitives-scroll-area.mjs +6 -3
  25. package/fesm2022/radix-ng-primitives-scroll-area.mjs.map +1 -1
  26. package/fesm2022/radix-ng-primitives-select.mjs +36 -12
  27. package/fesm2022/radix-ng-primitives-select.mjs.map +1 -1
  28. package/fesm2022/radix-ng-primitives-signal-forms.mjs +27 -11
  29. package/fesm2022/radix-ng-primitives-signal-forms.mjs.map +1 -1
  30. package/fesm2022/radix-ng-primitives-time-field.mjs +12 -6
  31. package/fesm2022/radix-ng-primitives-time-field.mjs.map +1 -1
  32. package/package.json +8 -3
  33. package/types/radix-ng-primitives-autocomplete.d.ts +7 -2
  34. package/types/radix-ng-primitives-checkbox.d.ts +10 -1
  35. package/types/radix-ng-primitives-combobox.d.ts +29 -2
  36. package/types/radix-ng-primitives-composite.d.ts +48 -2
  37. package/types/radix-ng-primitives-core.d.ts +152 -94
  38. package/types/radix-ng-primitives-date-field.d.ts +7 -4
  39. package/types/radix-ng-primitives-field.d.ts +55 -8
  40. package/types/radix-ng-primitives-form.d.ts +9 -0
  41. package/types/radix-ng-primitives-input.d.ts +10 -2
  42. package/types/radix-ng-primitives-menu.d.ts +45 -4
  43. package/types/radix-ng-primitives-navigation-menu.d.ts +2 -2
  44. package/types/radix-ng-primitives-popover.d.ts +2 -2
  45. package/types/radix-ng-primitives-popper.d.ts +60 -15
  46. package/types/radix-ng-primitives-preview-card.d.ts +2 -2
  47. package/types/radix-ng-primitives-select.d.ts +17 -3
  48. package/types/radix-ng-primitives-signal-forms.d.ts +22 -8
  49. package/types/radix-ng-primitives-time-field.d.ts +9 -6
  50. package/types/radix-ng-primitives-tooltip.d.ts +2 -2
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Directive, signal, computed, untracked, effect, inject, booleanAttribute, Injector, ElementRef, model, input, numberAttribute, output, isDevMode, DestroyRef, ChangeDetectionStrategy, Component, afterNextRender, afterRenderEffect, NgModule } from '@angular/core';
2
+ import { Directive, computed, signal, untracked, effect, inject, booleanAttribute, Injector, ElementRef, model, input, numberAttribute, output, isDevMode, DestroyRef, ChangeDetectionStrategy, Component, afterNextRender, afterRenderEffect, NgModule } from '@angular/core';
3
3
  import * as i1 from '@radix-ng/primitives/popper';
4
4
  import { RdxPopperAnchor, RdxPopperArrow, RdxPopper, RdxPopperContentWrapper, provideRdxPopperContentWrapper, provideRdxPopperContentConfig, DROPDOWN_COLLISION_AVOIDANCE, injectPopperContentWrapperContext, RdxPopperContent } from '@radix-ng/primitives/popper';
5
5
  import { NG_VALUE_ACCESSOR } from '@angular/forms';
@@ -66,7 +66,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImpor
66
66
  */
67
67
  function useComboboxEngine(config) {
68
68
  const { injector } = config;
69
- const defaultFilter = useFilter();
69
+ // Locale-aware default filter. A `computed` so changing `locale` rebuilds the collator and
70
+ // re-filters the list — mirrors Base UI, where `useFilter({ locale })` re-memoizes on change.
71
+ const defaultFilter = computed(() => useFilter({ locale: config.locale() }), /* @ts-ignore */
72
+ ...(ngDevMode ? [{ debugName: "defaultFilter" }] : /* istanbul ignore next */ []));
70
73
  const listId = injectId(config.listIdPrefix);
71
74
  const labelId = signal(undefined, /* @ts-ignore */
72
75
  ...(ngDevMode ? [{ debugName: "labelId" }] : /* istanbul ignore next */ []));
@@ -115,7 +118,7 @@ function useComboboxEngine(config) {
115
118
  // on the item's own text (the element content), no value→text round-trip.
116
119
  return filter
117
120
  ? filter(item.value(), query, config.itemToString)
118
- : defaultFilter.contains(item.textValue(), query);
121
+ : defaultFilter().contains(item.textValue(), query);
119
122
  };
120
123
  const visibleItems = computed(() => {
121
124
  const matching = orderedItems().filter((item) => matchesFilter(item));
@@ -147,7 +150,7 @@ function useComboboxEngine(config) {
147
150
  // Virtualized: no DOM to read text from, so resolve each value through `itemToString`.
148
151
  return cap(data.filter((value) => filter
149
152
  ? filter(value, query, config.itemToString)
150
- : defaultFilter.contains(config.itemToString(value), query)));
153
+ : defaultFilter().contains(config.itemToString(value), query)));
151
154
  }, /* @ts-ignore */
152
155
  ...(ngDevMode ? [{ debugName: "filteredItems" }] : /* istanbul ignore next */ []));
153
156
  const visibleCount = computed(() => (config.virtualized() ? filteredItems().length : visibleItems().length), /* @ts-ignore */
@@ -622,6 +625,8 @@ const context = () => {
622
625
  readonly: root.readOnly,
623
626
  requiredState: root.requiredState,
624
627
  invalidState: root.invalidState,
628
+ pendingState: root.formUi.pendingState,
629
+ validState: root.formUi.validState,
625
630
  touchedState: root.touchedState,
626
631
  dirtyState: root.dirtyState,
627
632
  openOnInputClick: root.openOnInputClick,
@@ -821,6 +826,9 @@ class RdxComboboxRoot extends RdxFormUiControlBase {
821
826
  */
822
827
  this.filter = input(undefined, /* @ts-ignore */
823
828
  ...(ngDevMode ? [{ debugName: "filter" }] : /* istanbul ignore next */ []));
829
+ /** Locale for the default `contains` filter's string comparison. Defaults to the runtime locale. */
830
+ this.locale = input(/* @ts-ignore */
831
+ ...(ngDevMode ? [undefined, { debugName: "locale" }] : /* istanbul ignore next */ []));
824
832
  /** Maximum number of matching items to show. `-1` (default) means no limit. */
825
833
  this.limit = input(-1, { ...(ngDevMode ? { debugName: "limit" } : /* istanbul ignore next */ {}), transform: numberAttribute });
826
834
  /**
@@ -870,6 +878,8 @@ class RdxComboboxRoot extends RdxFormUiControlBase {
870
878
  ...(ngDevMode ? [{ debugName: "requiredState" }] : /* istanbul ignore next */ []));
871
879
  /** @ignore */
872
880
  this.invalidState = this.formUi.invalidState;
881
+ this.pendingState = this.formUi.pendingState;
882
+ this.validState = this.formUi.validState;
873
883
  /** @ignore */
874
884
  this.touchedState = this.formUi.touchedState;
875
885
  /** @ignore */
@@ -907,6 +917,7 @@ class RdxComboboxRoot extends RdxFormUiControlBase {
907
917
  virtualized: this.virtualized,
908
918
  items: this.items,
909
919
  filter: this.filter,
920
+ locale: this.locale,
910
921
  limit: this.limit,
911
922
  grid: this.grid,
912
923
  rowOf: (element) => element.closest('[rdxComboboxRow]'),
@@ -1252,7 +1263,13 @@ class RdxComboboxRoot extends RdxFormUiControlBase {
1252
1263
  }
1253
1264
  // ControlValueAccessor
1254
1265
  writeValue(value) {
1255
- untracked(() => this.value.set(value));
1266
+ untracked(() => {
1267
+ this.value.set(value);
1268
+ // A programmatic form write (including reset) must keep the visible text aligned with the
1269
+ // committed selection. User commits already set the exact item text and do not echo through
1270
+ // this CVA callback; this path handles form-owned writes only.
1271
+ this.revertInputValue();
1272
+ });
1256
1273
  }
1257
1274
  registerOnChange(fn) {
1258
1275
  this.onChange = fn;
@@ -1264,7 +1281,7 @@ class RdxComboboxRoot extends RdxFormUiControlBase {
1264
1281
  this.cvaDisabled.set(isDisabled);
1265
1282
  }
1266
1283
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxComboboxRoot, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1267
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: RdxComboboxRoot, isStandalone: true, selector: "[rdxComboboxRoot]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, defaultValue: { classPropertyName: "defaultValue", publicName: "defaultValue", isSignal: true, isRequired: false, transformFunction: null }, inputValue: { classPropertyName: "inputValue", publicName: "inputValue", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, defaultOpen: { classPropertyName: "defaultOpen", publicName: "defaultOpen", isSignal: true, isRequired: false, transformFunction: null }, multipleInput: { classPropertyName: "multipleInput", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, fillInputOnItemPress: { classPropertyName: "fillInputOnItemPress", publicName: "fillInputOnItemPress", isSignal: true, isRequired: false, transformFunction: null }, dirInput: { classPropertyName: "dirInput", publicName: "dir", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readOnly: { classPropertyName: "readOnly", publicName: "readOnly", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, loopFocus: { classPropertyName: "loopFocus", publicName: "loopFocus", isSignal: true, isRequired: false, transformFunction: null }, autoHighlight: { classPropertyName: "autoHighlight", publicName: "autoHighlight", isSignal: true, isRequired: false, transformFunction: null }, highlightItemOnHover: { classPropertyName: "highlightItemOnHover", publicName: "highlightItemOnHover", isSignal: true, isRequired: false, transformFunction: null }, keepHighlight: { classPropertyName: "keepHighlight", publicName: "keepHighlight", isSignal: true, isRequired: false, transformFunction: null }, openOnInputClick: { classPropertyName: "openOnInputClick", publicName: "openOnInputClick", isSignal: true, isRequired: false, transformFunction: null }, modal: { classPropertyName: "modal", publicName: "modal", isSignal: true, isRequired: false, transformFunction: null }, submitOnItemClick: { classPropertyName: "submitOnItemClick", publicName: "submitOnItemClick", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, limit: { classPropertyName: "limit", publicName: "limit", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, virtualized: { classPropertyName: "virtualized", publicName: "virtualized", isSignal: true, isRequired: false, transformFunction: null }, grid: { classPropertyName: "grid", publicName: "grid", isSignal: true, isRequired: false, transformFunction: null }, isItemEqualToValue: { classPropertyName: "isItemEqualToValue", publicName: "isItemEqualToValue", isSignal: true, isRequired: false, transformFunction: null }, itemToStringLabel: { classPropertyName: "itemToStringLabel", publicName: "itemToStringLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", inputValue: "inputValueChange", open: "openChange", onValueChange: "onValueChange", onInputValueChange: "onInputValueChange", onOpenChange: "onOpenChange", onItemHighlighted: "onItemHighlighted", onOpenChangeComplete: "onOpenChangeComplete" }, host: { properties: { "attr.data-disabled": "disabledState() ? \"\" : undefined" } }, providers: [
1284
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: RdxComboboxRoot, isStandalone: true, selector: "[rdxComboboxRoot]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, defaultValue: { classPropertyName: "defaultValue", publicName: "defaultValue", isSignal: true, isRequired: false, transformFunction: null }, inputValue: { classPropertyName: "inputValue", publicName: "inputValue", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, defaultOpen: { classPropertyName: "defaultOpen", publicName: "defaultOpen", isSignal: true, isRequired: false, transformFunction: null }, multipleInput: { classPropertyName: "multipleInput", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, fillInputOnItemPress: { classPropertyName: "fillInputOnItemPress", publicName: "fillInputOnItemPress", isSignal: true, isRequired: false, transformFunction: null }, dirInput: { classPropertyName: "dirInput", publicName: "dir", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readOnly: { classPropertyName: "readOnly", publicName: "readOnly", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, loopFocus: { classPropertyName: "loopFocus", publicName: "loopFocus", isSignal: true, isRequired: false, transformFunction: null }, autoHighlight: { classPropertyName: "autoHighlight", publicName: "autoHighlight", isSignal: true, isRequired: false, transformFunction: null }, highlightItemOnHover: { classPropertyName: "highlightItemOnHover", publicName: "highlightItemOnHover", isSignal: true, isRequired: false, transformFunction: null }, keepHighlight: { classPropertyName: "keepHighlight", publicName: "keepHighlight", isSignal: true, isRequired: false, transformFunction: null }, openOnInputClick: { classPropertyName: "openOnInputClick", publicName: "openOnInputClick", isSignal: true, isRequired: false, transformFunction: null }, modal: { classPropertyName: "modal", publicName: "modal", isSignal: true, isRequired: false, transformFunction: null }, submitOnItemClick: { classPropertyName: "submitOnItemClick", publicName: "submitOnItemClick", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, limit: { classPropertyName: "limit", publicName: "limit", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, virtualized: { classPropertyName: "virtualized", publicName: "virtualized", isSignal: true, isRequired: false, transformFunction: null }, grid: { classPropertyName: "grid", publicName: "grid", isSignal: true, isRequired: false, transformFunction: null }, isItemEqualToValue: { classPropertyName: "isItemEqualToValue", publicName: "isItemEqualToValue", isSignal: true, isRequired: false, transformFunction: null }, itemToStringLabel: { classPropertyName: "itemToStringLabel", publicName: "itemToStringLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", inputValue: "inputValueChange", open: "openChange", onValueChange: "onValueChange", onInputValueChange: "onInputValueChange", onOpenChange: "onOpenChange", onItemHighlighted: "onItemHighlighted", onOpenChangeComplete: "onOpenChangeComplete" }, host: { properties: { "attr.data-disabled": "disabledState() ? \"\" : undefined" } }, providers: [
1268
1285
  provideComboboxRootContext(context),
1269
1286
  { provide: NG_VALUE_ACCESSOR, useExisting: RdxComboboxRoot, multi: true },
1270
1287
  // New floating foundation (ADR 0015/0017) — the dismissal capability reads this shared context.
@@ -1289,7 +1306,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImpor
1289
1306
  '[attr.data-disabled]': 'disabledState() ? "" : undefined'
1290
1307
  }
1291
1308
  }]
1292
- }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], defaultValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValue", required: false }] }], inputValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputValue", required: false }] }, { type: i0.Output, args: ["inputValueChange"] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], defaultOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultOpen", required: false }] }], multipleInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], selectionMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionMode", required: false }] }], fillInputOnItemPress: [{ type: i0.Input, args: [{ isSignal: true, alias: "fillInputOnItemPress", required: false }] }], dirInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "dir", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readOnly", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], loopFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "loopFocus", required: false }] }], autoHighlight: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoHighlight", required: false }] }], highlightItemOnHover: [{ type: i0.Input, args: [{ isSignal: true, alias: "highlightItemOnHover", required: false }] }], keepHighlight: [{ type: i0.Input, args: [{ isSignal: true, alias: "keepHighlight", required: false }] }], openOnInputClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "openOnInputClick", required: false }] }], modal: [{ type: i0.Input, args: [{ isSignal: true, alias: "modal", required: false }] }], submitOnItemClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "submitOnItemClick", required: false }] }], filter: [{ type: i0.Input, args: [{ isSignal: true, alias: "filter", required: false }] }], limit: [{ type: i0.Input, args: [{ isSignal: true, alias: "limit", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], virtualized: [{ type: i0.Input, args: [{ isSignal: true, alias: "virtualized", required: false }] }], grid: [{ type: i0.Input, args: [{ isSignal: true, alias: "grid", required: false }] }], isItemEqualToValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "isItemEqualToValue", required: false }] }], itemToStringLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemToStringLabel", required: false }] }], onValueChange: [{ type: i0.Output, args: ["onValueChange"] }], onInputValueChange: [{ type: i0.Output, args: ["onInputValueChange"] }], onOpenChange: [{ type: i0.Output, args: ["onOpenChange"] }], onItemHighlighted: [{ type: i0.Output, args: ["onItemHighlighted"] }], onOpenChangeComplete: [{ type: i0.Output, args: ["onOpenChangeComplete"] }] } });
1309
+ }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], defaultValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValue", required: false }] }], inputValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputValue", required: false }] }, { type: i0.Output, args: ["inputValueChange"] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], defaultOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultOpen", required: false }] }], multipleInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], selectionMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionMode", required: false }] }], fillInputOnItemPress: [{ type: i0.Input, args: [{ isSignal: true, alias: "fillInputOnItemPress", required: false }] }], dirInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "dir", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readOnly", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], loopFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "loopFocus", required: false }] }], autoHighlight: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoHighlight", required: false }] }], highlightItemOnHover: [{ type: i0.Input, args: [{ isSignal: true, alias: "highlightItemOnHover", required: false }] }], keepHighlight: [{ type: i0.Input, args: [{ isSignal: true, alias: "keepHighlight", required: false }] }], openOnInputClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "openOnInputClick", required: false }] }], modal: [{ type: i0.Input, args: [{ isSignal: true, alias: "modal", required: false }] }], submitOnItemClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "submitOnItemClick", required: false }] }], filter: [{ type: i0.Input, args: [{ isSignal: true, alias: "filter", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], limit: [{ type: i0.Input, args: [{ isSignal: true, alias: "limit", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], virtualized: [{ type: i0.Input, args: [{ isSignal: true, alias: "virtualized", required: false }] }], grid: [{ type: i0.Input, args: [{ isSignal: true, alias: "grid", required: false }] }], isItemEqualToValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "isItemEqualToValue", required: false }] }], itemToStringLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemToStringLabel", required: false }] }], onValueChange: [{ type: i0.Output, args: ["onValueChange"] }], onInputValueChange: [{ type: i0.Output, args: ["onInputValueChange"] }], onOpenChange: [{ type: i0.Output, args: ["onOpenChange"] }], onItemHighlighted: [{ type: i0.Output, args: ["onItemHighlighted"] }], onOpenChangeComplete: [{ type: i0.Output, args: ["onOpenChangeComplete"] }] } });
1293
1310
 
1294
1311
  /**
1295
1312
  * An overlay rendered beneath the popup in `modal` mode. Place it inside the portal/presence; style
@@ -1769,18 +1786,21 @@ class RdxComboboxInput {
1769
1786
  ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
1770
1787
  /** Marks the input as invalid independently of any Field state. */
1771
1788
  this.invalid = input(false, { ...(ngDevMode ? { debugName: "invalid" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1772
- this.invalidState = computed(() => this.invalid() || this.rootContext.invalidState() || Boolean(this.fieldRootContext?.invalidState()), /* @ts-ignore */
1773
- ...(ngDevMode ? [{ debugName: "invalidState" }] : /* istanbul ignore next */ []));
1774
1789
  /**
1775
1790
  * Tri-state *displayed* validity: the enclosing Field's gated `validState` when inside a `rdxFieldRoot`
1776
1791
  * (so a field whose `validationMode` defers display (e.g. `onBlur`) keeps the input neutral until revealed), else the input's
1777
1792
  * own binary invalidity.
1778
1793
  */
1779
- this.displayValid = computed(() => this.fieldRootContext
1780
- ? this.fieldRootContext.validState()
1781
- : this.invalid() || this.rootContext.invalidState()
1782
- ? false
1783
- : true, /* @ts-ignore */
1794
+ this.displayValid = computed(() => {
1795
+ if (this.fieldRootContext) {
1796
+ return this.fieldRootContext.validState();
1797
+ }
1798
+ const rootValid = this.rootContext.validState();
1799
+ if (rootValid === null) {
1800
+ return null;
1801
+ }
1802
+ return this.invalid() ? false : rootValid;
1803
+ }, /* @ts-ignore */
1784
1804
  ...(ngDevMode ? [{ debugName: "displayValid" }] : /* istanbul ignore next */ []));
1785
1805
  this.disabledState = computed(() => this.rootContext.disabledState() || Boolean(this.fieldRootContext?.disabledState()), /* @ts-ignore */
1786
1806
  ...(ngDevMode ? [{ debugName: "disabledState" }] : /* istanbul ignore next */ []));
@@ -1806,10 +1826,7 @@ class RdxComboboxInput {
1806
1826
  if (!this.fieldRootContext) {
1807
1827
  return undefined;
1808
1828
  }
1809
- const ids = [
1810
- ...this.fieldRootContext.descriptionIds(),
1811
- ...(this.fieldRootContext.invalidState() ? this.fieldRootContext.errorIds() : [])
1812
- ];
1829
+ const ids = [...this.fieldRootContext.descriptionIds(), ...this.fieldRootContext.errorIds()];
1813
1830
  return ids.length ? ids.join(' ') : undefined;
1814
1831
  }, /* @ts-ignore */
1815
1832
  ...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));