@radix-ng/primitives 1.0.10 → 1.1.1
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.
- package/README.md +26 -5
- package/fesm2022/radix-ng-primitives-autocomplete.mjs +88 -21
- package/fesm2022/radix-ng-primitives-autocomplete.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-checkbox.mjs +199 -129
- package/fesm2022/radix-ng-primitives-checkbox.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-combobox.mjs +203 -52
- package/fesm2022/radix-ng-primitives-combobox.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-composite.mjs +221 -36
- package/fesm2022/radix-ng-primitives-composite.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-core.mjs +352 -24
- package/fesm2022/radix-ng-primitives-core.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-date-field.mjs +11 -5
- package/fesm2022/radix-ng-primitives-date-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-field.mjs +127 -23
- package/fesm2022/radix-ng-primitives-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-form.mjs +35 -4
- package/fesm2022/radix-ng-primitives-form.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-input.mjs +87 -15
- package/fesm2022/radix-ng-primitives-input.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-menu.mjs +34 -7
- package/fesm2022/radix-ng-primitives-menu.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-number-field.mjs +38 -7
- package/fesm2022/radix-ng-primitives-number-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-popper.mjs +80 -11
- package/fesm2022/radix-ng-primitives-popper.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-radio.mjs +49 -2
- package/fesm2022/radix-ng-primitives-radio.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-scroll-area.mjs +6 -3
- package/fesm2022/radix-ng-primitives-scroll-area.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-select.mjs +70 -14
- package/fesm2022/radix-ng-primitives-select.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-signal-forms.mjs +27 -11
- package/fesm2022/radix-ng-primitives-signal-forms.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-slider.mjs +17 -2
- package/fesm2022/radix-ng-primitives-slider.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-switch.mjs +60 -7
- package/fesm2022/radix-ng-primitives-switch.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-time-field.mjs +12 -6
- package/fesm2022/radix-ng-primitives-time-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toggle-group.mjs +25 -3
- package/fesm2022/radix-ng-primitives-toggle-group.mjs.map +1 -1
- package/package.json +8 -3
- package/types/radix-ng-primitives-autocomplete.d.ts +16 -2
- package/types/radix-ng-primitives-checkbox.d.ts +66 -44
- package/types/radix-ng-primitives-combobox.d.ts +74 -3
- package/types/radix-ng-primitives-composite.d.ts +48 -2
- package/types/radix-ng-primitives-core.d.ts +212 -96
- package/types/radix-ng-primitives-date-field.d.ts +7 -4
- package/types/radix-ng-primitives-field.d.ts +55 -8
- package/types/radix-ng-primitives-form.d.ts +9 -0
- package/types/radix-ng-primitives-input.d.ts +10 -2
- package/types/radix-ng-primitives-menu.d.ts +45 -4
- package/types/radix-ng-primitives-navigation-menu.d.ts +2 -2
- package/types/radix-ng-primitives-number-field.d.ts +12 -5
- package/types/radix-ng-primitives-popover.d.ts +2 -2
- package/types/radix-ng-primitives-popper.d.ts +60 -15
- package/types/radix-ng-primitives-preview-card.d.ts +2 -2
- package/types/radix-ng-primitives-radio.d.ts +6 -1
- package/types/radix-ng-primitives-select.d.ts +25 -4
- package/types/radix-ng-primitives-signal-forms.d.ts +22 -8
- package/types/radix-ng-primitives-slider.d.ts +2 -1
- package/types/radix-ng-primitives-switch.d.ts +19 -3
- package/types/radix-ng-primitives-time-field.d.ts +9 -6
- package/types/radix-ng-primitives-toggle-group.d.ts +5 -1
- package/types/radix-ng-primitives-tooltip.d.ts +2 -2
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Directive,
|
|
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';
|
|
6
6
|
import * as i2 from '@radix-ng/primitives/core';
|
|
7
|
-
import { useFilter, injectId, useListHighlight, useTransitionStatus, createContext, RdxFormUiControlBase, createFloatingRootContext, isItemEqualToValue, isNullish, createCancelableChangeEventDetails, itemToStringLabel, provideFloatingTree, provideFloatingRootContext, setupInternalBackdrop, RDX_FLOATING_ROOT_CONTEXT, RDX_FLOATING_REGISTRATION, useAnchoredScrollLock, RdxFloatingNodeRegistration, rdxDevError } from '@radix-ng/primitives/core';
|
|
7
|
+
import { useFilter, injectId, useListHighlight, useTransitionStatus, createContext, RdxFormUiControlBase, createFloatingRootContext, useNativeFormControl, serializeNativeFormValue, isItemEqualToValue, isNullish, createCancelableChangeEventDetails, itemToStringLabel, provideFloatingTree, provideFloatingRootContext, setupInternalBackdrop, RDX_FLOATING_ROOT_CONTEXT, RDX_FLOATING_REGISTRATION, useAnchoredScrollLock, RdxFloatingNodeRegistration, rdxDevError } from '@radix-ng/primitives/core';
|
|
8
8
|
import { injectDirection } from '@radix-ng/primitives/direction-provider';
|
|
9
9
|
import * as i1$1 from '@radix-ng/primitives/dismissable-layer';
|
|
10
10
|
import { RdxFloatingInsideElement, RdxDismiss } from '@radix-ng/primitives/dismissable-layer';
|
|
@@ -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
|
-
|
|
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 */ []));
|
|
@@ -95,34 +98,58 @@ function useComboboxEngine(config) {
|
|
|
95
98
|
// Tracks whether the last interaction was the keyboard, so the highlight doesn't jump to an item
|
|
96
99
|
// the cursor happens to rest on when arrow-key navigation scrolls the list under a still pointer.
|
|
97
100
|
let keyboardActive = false;
|
|
98
|
-
|
|
99
|
-
|
|
101
|
+
// Keep registrations in a stable map. Copying the growing array on every item mount/unmount makes
|
|
102
|
+
// registering N options O(n²) before filtering or DOM-order sorting even begins. The numeric tick is
|
|
103
|
+
// only the reactive invalidation channel; Angular batches the registrations from one render, so
|
|
104
|
+
// `orderedItems` materializes and sorts the final collection once for that batch. This is the same
|
|
105
|
+
// stable-map pattern used by Base UI and our CompositeList.
|
|
106
|
+
const itemRegistry = new Map();
|
|
107
|
+
const itemRegistryTick = signal(0, /* @ts-ignore */
|
|
108
|
+
...(ngDevMode ? [{ debugName: "itemRegistryTick" }] : /* istanbul ignore next */ []));
|
|
100
109
|
const orderedItems = computed(() => {
|
|
101
|
-
|
|
102
|
-
return
|
|
110
|
+
itemRegistryTick();
|
|
111
|
+
return [...itemRegistry.values()]
|
|
112
|
+
.filter((item) => item.element.isConnected)
|
|
113
|
+
.sort((a, b) => domOrder(a.element, b.element));
|
|
103
114
|
}, /* @ts-ignore */
|
|
104
115
|
...(ngDevMode ? [{ debugName: "orderedItems" }] : /* istanbul ignore next */ []));
|
|
105
|
-
const
|
|
116
|
+
const visibleItems = computed(() => {
|
|
117
|
+
const items = orderedItems();
|
|
118
|
+
const limit = config.limit();
|
|
119
|
+
if (limit === 0) {
|
|
120
|
+
return [];
|
|
121
|
+
}
|
|
122
|
+
// Read root signals once per query, not once per item. The early paths also avoid
|
|
123
|
+
// allocating/filtering when every registered item is known to be visible.
|
|
106
124
|
if (!config.filteringEnabled()) {
|
|
107
|
-
return
|
|
125
|
+
return limit >= 0 ? items.slice(0, limit) : items;
|
|
108
126
|
}
|
|
109
127
|
const filter = config.filter();
|
|
110
128
|
if (filter === null) {
|
|
111
|
-
return
|
|
129
|
+
return limit >= 0 ? items.slice(0, limit) : items;
|
|
112
130
|
}
|
|
113
131
|
const query = config.query();
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
132
|
+
if (!filter && query.length === 0) {
|
|
133
|
+
return limit >= 0 ? items.slice(0, limit) : items;
|
|
134
|
+
}
|
|
135
|
+
const matching = [];
|
|
136
|
+
const contains = filter ? null : defaultFilter().contains;
|
|
137
|
+
for (const item of items) {
|
|
138
|
+
// Custom filter: Base UI shape `(value, query, itemToString)`. Default: locale-aware
|
|
139
|
+
// contains on the item's own text (the element content), no value→text round-trip.
|
|
140
|
+
const matches = filter
|
|
141
|
+
? filter(item.value(), query, config.itemToString)
|
|
142
|
+
: contains(item.textValue(), query);
|
|
143
|
+
if (!matches) {
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
matching.push(item);
|
|
147
|
+
if (limit >= 0 && matching.length >= limit) {
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return matching;
|
|
152
|
+
}, { ...(ngDevMode ? { debugName: "visibleItems" } : /* istanbul ignore next */ {}), equal: sameItemOrder });
|
|
126
153
|
const visibleSet = computed(() => new Set(visibleItems()), /* @ts-ignore */
|
|
127
154
|
...(ngDevMode ? [{ debugName: "visibleSet" }] : /* istanbul ignore next */ []));
|
|
128
155
|
const isVisible = (item) => visibleSet().has(item);
|
|
@@ -147,7 +174,7 @@ function useComboboxEngine(config) {
|
|
|
147
174
|
// Virtualized: no DOM to read text from, so resolve each value through `itemToString`.
|
|
148
175
|
return cap(data.filter((value) => filter
|
|
149
176
|
? filter(value, query, config.itemToString)
|
|
150
|
-
: defaultFilter.contains(config.itemToString(value), query)));
|
|
177
|
+
: defaultFilter().contains(config.itemToString(value), query)));
|
|
151
178
|
}, /* @ts-ignore */
|
|
152
179
|
...(ngDevMode ? [{ debugName: "filteredItems" }] : /* istanbul ignore next */ []));
|
|
153
180
|
const visibleCount = computed(() => (config.virtualized() ? filteredItems().length : visibleItems().length), /* @ts-ignore */
|
|
@@ -221,7 +248,13 @@ function useComboboxEngine(config) {
|
|
|
221
248
|
};
|
|
222
249
|
const recomputeInlinePreview = (label, query, reason) => {
|
|
223
250
|
// Pointer hover must not rewrite the input (matches Base UI); only typing / keyboard nav complete it.
|
|
224
|
-
if (!config.inlineMode() ||
|
|
251
|
+
if (!config.inlineMode() || !label || reason === 'pointer') {
|
|
252
|
+
inlinePreview.set(null);
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
// Suppression belongs to the current edit only. Explicit keyboard navigation starts a new
|
|
256
|
+
// interaction and must still mirror the navigated label after a delete/cut edit.
|
|
257
|
+
if (suppressInline && reason !== 'keyboard') {
|
|
225
258
|
inlinePreview.set(null);
|
|
226
259
|
return;
|
|
227
260
|
}
|
|
@@ -313,11 +346,14 @@ function useComboboxEngine(config) {
|
|
|
313
346
|
pendingHighlightEdge.set(null);
|
|
314
347
|
});
|
|
315
348
|
}, { injector });
|
|
316
|
-
// Inline completion: mirror the active item's label into the input.
|
|
317
|
-
//
|
|
318
|
-
// `both → list`
|
|
349
|
+
// Inline completion: mirror the active item's label into the input. When inline mode is off, stop
|
|
350
|
+
// before reading query/highlight state so Combobox and list-mode Autocomplete do not subscribe this
|
|
351
|
+
// effect to the typing hot path. A `both → list` switch still clears the previous preview.
|
|
319
352
|
effect(() => {
|
|
320
|
-
config.inlineMode()
|
|
353
|
+
if (!config.inlineMode()) {
|
|
354
|
+
untracked(() => inlinePreview.set(null));
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
321
357
|
highlightedItem();
|
|
322
358
|
highlightedIndex();
|
|
323
359
|
const query = config.query();
|
|
@@ -456,10 +492,19 @@ function useComboboxEngine(config) {
|
|
|
456
492
|
filteredItems,
|
|
457
493
|
isVisible,
|
|
458
494
|
registerItem(item) {
|
|
459
|
-
|
|
495
|
+
if (itemRegistry.get(item.element) === item) {
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
498
|
+
itemRegistry.set(item.element, item);
|
|
499
|
+
itemRegistryTick.update((tick) => tick + 1);
|
|
460
500
|
},
|
|
461
501
|
unregisterItem(item) {
|
|
462
|
-
|
|
502
|
+
// A stale cleanup must not delete a newer registration for the same host element.
|
|
503
|
+
if (itemRegistry.get(item.element) !== item) {
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
itemRegistry.delete(item.element);
|
|
507
|
+
itemRegistryTick.update((tick) => tick + 1);
|
|
463
508
|
},
|
|
464
509
|
highlight,
|
|
465
510
|
highlightedItem,
|
|
@@ -600,6 +645,21 @@ function domOrder(a, b) {
|
|
|
600
645
|
}
|
|
601
646
|
return 0;
|
|
602
647
|
}
|
|
648
|
+
/** Referential item-sequence equality used to keep unchanged filtering results stable across queries. */
|
|
649
|
+
function sameItemOrder(previous, next) {
|
|
650
|
+
if (previous === next) {
|
|
651
|
+
return true;
|
|
652
|
+
}
|
|
653
|
+
if (previous.length !== next.length) {
|
|
654
|
+
return false;
|
|
655
|
+
}
|
|
656
|
+
for (let index = 0; index < previous.length; index++) {
|
|
657
|
+
if (previous[index] !== next[index]) {
|
|
658
|
+
return false;
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
return true;
|
|
662
|
+
}
|
|
603
663
|
|
|
604
664
|
// The engine stays private to the root (it owns mutable internals); the context factory — a free
|
|
605
665
|
// function, so it can't reach a `private` field — reads it through this registry instead.
|
|
@@ -614,6 +674,9 @@ const context = () => {
|
|
|
614
674
|
dir: root.dir,
|
|
615
675
|
value: root.value,
|
|
616
676
|
inputValue: root.inputValue,
|
|
677
|
+
name: root.name,
|
|
678
|
+
form: root.form,
|
|
679
|
+
inputOwnsFormValue: root.inputOwnsFormValue,
|
|
617
680
|
open: root.open,
|
|
618
681
|
present: root.present,
|
|
619
682
|
multiple: root.multiple,
|
|
@@ -622,6 +685,8 @@ const context = () => {
|
|
|
622
685
|
readonly: root.readOnly,
|
|
623
686
|
requiredState: root.requiredState,
|
|
624
687
|
invalidState: root.invalidState,
|
|
688
|
+
pendingState: root.formUi.pendingState,
|
|
689
|
+
validState: root.formUi.validState,
|
|
625
690
|
touchedState: root.touchedState,
|
|
626
691
|
dirtyState: root.dirtyState,
|
|
627
692
|
openOnInputClick: root.openOnInputClick,
|
|
@@ -763,6 +828,9 @@ class RdxComboboxRoot extends RdxFormUiControlBase {
|
|
|
763
828
|
/** Whether the combobox is in multiple-selection mode. */
|
|
764
829
|
this.multiple = computed(() => this.mode() === 'multiple', /* @ts-ignore */
|
|
765
830
|
...(ngDevMode ? [{ debugName: "multiple" }] : /* istanbul ignore next */ []));
|
|
831
|
+
/** Whether the visible text input owns native serialization in filter-only mode. */
|
|
832
|
+
this.inputOwnsFormValue = computed(() => this.mode() === 'none' && this.engine.inputLayout() !== 'inside', /* @ts-ignore */
|
|
833
|
+
...(ngDevMode ? [{ debugName: "inputOwnsFormValue" }] : /* istanbul ignore next */ []));
|
|
766
834
|
/** In `'none'` mode, whether pressing an item fills the input with its label. */
|
|
767
835
|
this.fillInputOnItemPress = input(true, { ...(ngDevMode ? { debugName: "fillInputOnItemPress" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
768
836
|
/** Text direction. */
|
|
@@ -774,6 +842,12 @@ class RdxComboboxRoot extends RdxFormUiControlBase {
|
|
|
774
842
|
this.readOnly = input(false, { ...(ngDevMode ? { debugName: "readOnly" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
775
843
|
/** Whether a value is required (for forms). */
|
|
776
844
|
this.required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
845
|
+
/** Name used when serializing the committed selection into native `FormData`. */
|
|
846
|
+
this.name = input(/* @ts-ignore */
|
|
847
|
+
...(ngDevMode ? [undefined, { debugName: "name" }] : /* istanbul ignore next */ []));
|
|
848
|
+
/** Id of an external form that owns this control. */
|
|
849
|
+
this.form = input(/* @ts-ignore */
|
|
850
|
+
...(ngDevMode ? [undefined, { debugName: "form" }] : /* istanbul ignore next */ []));
|
|
777
851
|
/** Whether keyboard navigation wraps at the list boundaries. */
|
|
778
852
|
this.loopFocus = input(true, { ...(ngDevMode ? { debugName: "loopFocus" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
779
853
|
/**
|
|
@@ -821,6 +895,9 @@ class RdxComboboxRoot extends RdxFormUiControlBase {
|
|
|
821
895
|
*/
|
|
822
896
|
this.filter = input(undefined, /* @ts-ignore */
|
|
823
897
|
...(ngDevMode ? [{ debugName: "filter" }] : /* istanbul ignore next */ []));
|
|
898
|
+
/** Locale for the default `contains` filter's string comparison. Defaults to the runtime locale. */
|
|
899
|
+
this.locale = input(/* @ts-ignore */
|
|
900
|
+
...(ngDevMode ? [undefined, { debugName: "locale" }] : /* istanbul ignore next */ []));
|
|
824
901
|
/** Maximum number of matching items to show. `-1` (default) means no limit. */
|
|
825
902
|
this.limit = input(-1, { ...(ngDevMode ? { debugName: "limit" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
826
903
|
/**
|
|
@@ -849,6 +926,9 @@ class RdxComboboxRoot extends RdxFormUiControlBase {
|
|
|
849
926
|
/** Converts a value to its display label. Defaults to the matching item's text. */
|
|
850
927
|
this.itemToStringLabel = input(/* @ts-ignore */
|
|
851
928
|
...(ngDevMode ? [undefined, { debugName: "itemToStringLabel" }] : /* istanbul ignore next */ []));
|
|
929
|
+
/** Converts an item value to the string submitted by a native form. */
|
|
930
|
+
this.itemToStringValue = input(/* @ts-ignore */
|
|
931
|
+
...(ngDevMode ? [undefined, { debugName: "itemToStringValue" }] : /* istanbul ignore next */ []));
|
|
852
932
|
/** Emits before the selection changes; call `eventDetails.cancel()` to veto it. */
|
|
853
933
|
this.onValueChange = output();
|
|
854
934
|
/** Emits before the input text changes; call `eventDetails.cancel()` to veto it. */
|
|
@@ -866,10 +946,52 @@ class RdxComboboxRoot extends RdxFormUiControlBase {
|
|
|
866
946
|
...(ngDevMode ? [{ debugName: "cvaDisabled" }] : /* istanbul ignore next */ []));
|
|
867
947
|
this.disabledState = computed(() => this.disabled() || this.cvaDisabled(), /* @ts-ignore */
|
|
868
948
|
...(ngDevMode ? [{ debugName: "disabledState" }] : /* istanbul ignore next */ []));
|
|
949
|
+
this.nativeFormValue = computed(() => this.mode() === 'none' ? this.inputValue() : this.value(), /* @ts-ignore */
|
|
950
|
+
...(ngDevMode ? [{ debugName: "nativeFormValue" }] : /* istanbul ignore next */ []));
|
|
951
|
+
this.nativeFormControl = useNativeFormControl({
|
|
952
|
+
name: this.name,
|
|
953
|
+
form: this.form,
|
|
954
|
+
disabled: this.disabledState,
|
|
955
|
+
value: this.nativeFormValue,
|
|
956
|
+
serialize: (value) => {
|
|
957
|
+
const itemToStringValue = this.itemToStringValue();
|
|
958
|
+
return itemToStringValue
|
|
959
|
+
? serializeNativeFormValue(value, (entry) => itemToStringValue(entry))
|
|
960
|
+
: serializeNativeFormValue(value);
|
|
961
|
+
},
|
|
962
|
+
hasNativeControl: this.inputOwnsFormValue,
|
|
963
|
+
syncNativeControl: () => {
|
|
964
|
+
const input = this.engine.inputElement();
|
|
965
|
+
if (input && this.inputOwnsFormValue()) {
|
|
966
|
+
input.value = this.inputValue();
|
|
967
|
+
}
|
|
968
|
+
},
|
|
969
|
+
defaultValue: () => {
|
|
970
|
+
if (this.mode() === 'none') {
|
|
971
|
+
return this.inputValue();
|
|
972
|
+
}
|
|
973
|
+
const defaultValue = this.defaultValue();
|
|
974
|
+
return defaultValue === undefined ? this.value() : defaultValue;
|
|
975
|
+
},
|
|
976
|
+
onReset: (value) => {
|
|
977
|
+
if (this.mode() === 'none') {
|
|
978
|
+
this.setLabel(typeof value === 'string' ? value : '');
|
|
979
|
+
this.formUi.resetInteractionState?.();
|
|
980
|
+
return;
|
|
981
|
+
}
|
|
982
|
+
this.writeValue(value);
|
|
983
|
+
if (!this.resetNgControl(value)) {
|
|
984
|
+
this.onChange?.(value);
|
|
985
|
+
}
|
|
986
|
+
this.formUi.resetInteractionState?.();
|
|
987
|
+
}
|
|
988
|
+
});
|
|
869
989
|
this.requiredState = computed(() => this.required(), /* @ts-ignore */
|
|
870
990
|
...(ngDevMode ? [{ debugName: "requiredState" }] : /* istanbul ignore next */ []));
|
|
871
991
|
/** @ignore */
|
|
872
992
|
this.invalidState = this.formUi.invalidState;
|
|
993
|
+
this.pendingState = this.formUi.pendingState;
|
|
994
|
+
this.validState = this.formUi.validState;
|
|
873
995
|
/** @ignore */
|
|
874
996
|
this.touchedState = this.formUi.touchedState;
|
|
875
997
|
/** @ignore */
|
|
@@ -907,6 +1029,7 @@ class RdxComboboxRoot extends RdxFormUiControlBase {
|
|
|
907
1029
|
virtualized: this.virtualized,
|
|
908
1030
|
items: this.items,
|
|
909
1031
|
filter: this.filter,
|
|
1032
|
+
locale: this.locale,
|
|
910
1033
|
limit: this.limit,
|
|
911
1034
|
grid: this.grid,
|
|
912
1035
|
rowOf: (element) => element.closest('[rdxComboboxRow]'),
|
|
@@ -1146,7 +1269,7 @@ class RdxComboboxRoot extends RdxFormUiControlBase {
|
|
|
1146
1269
|
/** Requests submit of the closest form when `submitOnItemClick` is enabled. */
|
|
1147
1270
|
maybeSubmit() {
|
|
1148
1271
|
if (this.submitOnItemClick()) {
|
|
1149
|
-
this.
|
|
1272
|
+
this.nativeFormControl.requestSubmit();
|
|
1150
1273
|
}
|
|
1151
1274
|
}
|
|
1152
1275
|
selectHighlighted(event = new Event('combobox.item-press')) {
|
|
@@ -1252,7 +1375,13 @@ class RdxComboboxRoot extends RdxFormUiControlBase {
|
|
|
1252
1375
|
}
|
|
1253
1376
|
// ControlValueAccessor
|
|
1254
1377
|
writeValue(value) {
|
|
1255
|
-
untracked(() =>
|
|
1378
|
+
untracked(() => {
|
|
1379
|
+
this.value.set(value);
|
|
1380
|
+
// A programmatic form write (including reset) must keep the visible text aligned with the
|
|
1381
|
+
// committed selection. User commits already set the exact item text and do not echo through
|
|
1382
|
+
// this CVA callback; this path handles form-owned writes only.
|
|
1383
|
+
this.revertInputValue();
|
|
1384
|
+
});
|
|
1256
1385
|
}
|
|
1257
1386
|
registerOnChange(fn) {
|
|
1258
1387
|
this.onChange = fn;
|
|
@@ -1264,7 +1393,7 @@ class RdxComboboxRoot extends RdxFormUiControlBase {
|
|
|
1264
1393
|
this.cvaDisabled.set(isDisabled);
|
|
1265
1394
|
}
|
|
1266
1395
|
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: [
|
|
1396
|
+
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 }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", 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 }, itemToStringValue: { classPropertyName: "itemToStringValue", publicName: "itemToStringValue", 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
1397
|
provideComboboxRootContext(context),
|
|
1269
1398
|
{ provide: NG_VALUE_ACCESSOR, useExisting: RdxComboboxRoot, multi: true },
|
|
1270
1399
|
// New floating foundation (ADR 0015/0017) — the dismissal capability reads this shared context.
|
|
@@ -1289,7 +1418,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImpor
|
|
|
1289
1418
|
'[attr.data-disabled]': 'disabledState() ? "" : undefined'
|
|
1290
1419
|
}
|
|
1291
1420
|
}]
|
|
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"] }] } });
|
|
1421
|
+
}], 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 }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", 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 }] }], itemToStringValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemToStringValue", 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
1422
|
|
|
1294
1423
|
/**
|
|
1295
1424
|
* An overlay rendered beneath the popup in `modal` mode. Place it inside the portal/presence; style
|
|
@@ -1620,18 +1749,38 @@ class RdxComboboxGroup {
|
|
|
1620
1749
|
this.rootContext = injectComboboxRootContext();
|
|
1621
1750
|
this.labelId = signal(undefined, /* @ts-ignore */
|
|
1622
1751
|
...(ngDevMode ? [{ debugName: "labelId" }] : /* istanbul ignore next */ []));
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
this.
|
|
1752
|
+
// Group membership is unordered, so a stable Set avoids copying a growing array for every child
|
|
1753
|
+
// registration. The tick keeps the two derived host states reactive.
|
|
1754
|
+
this.items = new Set();
|
|
1755
|
+
this.itemsTick = signal(0, /* @ts-ignore */
|
|
1756
|
+
...(ngDevMode ? [{ debugName: "itemsTick" }] : /* istanbul ignore next */ []));
|
|
1757
|
+
this.hasItems = computed(() => {
|
|
1758
|
+
this.itemsTick();
|
|
1759
|
+
return this.items.size > 0;
|
|
1760
|
+
}, /* @ts-ignore */
|
|
1626
1761
|
...(ngDevMode ? [{ debugName: "hasItems" }] : /* istanbul ignore next */ []));
|
|
1627
|
-
this.hasVisibleItems = computed(() =>
|
|
1762
|
+
this.hasVisibleItems = computed(() => {
|
|
1763
|
+
this.itemsTick();
|
|
1764
|
+
for (const item of this.items) {
|
|
1765
|
+
if (this.rootContext.isVisible(item)) {
|
|
1766
|
+
return true;
|
|
1767
|
+
}
|
|
1768
|
+
}
|
|
1769
|
+
return false;
|
|
1770
|
+
}, /* @ts-ignore */
|
|
1628
1771
|
...(ngDevMode ? [{ debugName: "hasVisibleItems" }] : /* istanbul ignore next */ []));
|
|
1629
1772
|
}
|
|
1630
1773
|
registerItem(item) {
|
|
1631
|
-
this.items.
|
|
1774
|
+
if (this.items.has(item)) {
|
|
1775
|
+
return;
|
|
1776
|
+
}
|
|
1777
|
+
this.items.add(item);
|
|
1778
|
+
this.itemsTick.update((tick) => tick + 1);
|
|
1632
1779
|
}
|
|
1633
1780
|
unregisterItem(item) {
|
|
1634
|
-
this.items.
|
|
1781
|
+
if (this.items.delete(item)) {
|
|
1782
|
+
this.itemsTick.update((tick) => tick + 1);
|
|
1783
|
+
}
|
|
1635
1784
|
}
|
|
1636
1785
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxComboboxGroup, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1637
1786
|
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: RdxComboboxGroup, isStandalone: true, selector: "[rdxComboboxGroup]", host: { attributes: { "role": "group" }, properties: { "attr.aria-labelledby": "labelId()", "hidden": "hasItems() && !hasVisibleItems()" } }, providers: [provideComboboxGroupContext(groupContext)], exportAs: ["rdxComboboxGroup"], ngImport: i0 }); }
|
|
@@ -1769,18 +1918,21 @@ class RdxComboboxInput {
|
|
|
1769
1918
|
...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
1770
1919
|
/** Marks the input as invalid independently of any Field state. */
|
|
1771
1920
|
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
1921
|
/**
|
|
1775
1922
|
* Tri-state *displayed* validity: the enclosing Field's gated `validState` when inside a `rdxFieldRoot`
|
|
1776
1923
|
* (so a field whose `validationMode` defers display (e.g. `onBlur`) keeps the input neutral until revealed), else the input's
|
|
1777
1924
|
* own binary invalidity.
|
|
1778
1925
|
*/
|
|
1779
|
-
this.displayValid = computed(() =>
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1926
|
+
this.displayValid = computed(() => {
|
|
1927
|
+
if (this.fieldRootContext) {
|
|
1928
|
+
return this.fieldRootContext.validState();
|
|
1929
|
+
}
|
|
1930
|
+
const rootValid = this.rootContext.validState();
|
|
1931
|
+
if (rootValid === null) {
|
|
1932
|
+
return null;
|
|
1933
|
+
}
|
|
1934
|
+
return this.invalid() ? false : rootValid;
|
|
1935
|
+
}, /* @ts-ignore */
|
|
1784
1936
|
...(ngDevMode ? [{ debugName: "displayValid" }] : /* istanbul ignore next */ []));
|
|
1785
1937
|
this.disabledState = computed(() => this.rootContext.disabledState() || Boolean(this.fieldRootContext?.disabledState()), /* @ts-ignore */
|
|
1786
1938
|
...(ngDevMode ? [{ debugName: "disabledState" }] : /* istanbul ignore next */ []));
|
|
@@ -1806,10 +1958,7 @@ class RdxComboboxInput {
|
|
|
1806
1958
|
if (!this.fieldRootContext) {
|
|
1807
1959
|
return undefined;
|
|
1808
1960
|
}
|
|
1809
|
-
const ids = [
|
|
1810
|
-
...this.fieldRootContext.descriptionIds(),
|
|
1811
|
-
...(this.fieldRootContext.invalidState() ? this.fieldRootContext.errorIds() : [])
|
|
1812
|
-
];
|
|
1961
|
+
const ids = [...this.fieldRootContext.descriptionIds(), ...this.fieldRootContext.errorIds()];
|
|
1813
1962
|
return ids.length ? ids.join(' ') : undefined;
|
|
1814
1963
|
}, /* @ts-ignore */
|
|
1815
1964
|
...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));
|
|
@@ -1986,7 +2135,7 @@ class RdxComboboxInput {
|
|
|
1986
2135
|
}
|
|
1987
2136
|
}
|
|
1988
2137
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxComboboxInput, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1989
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: RdxComboboxInput, isStandalone: true, selector: "input[rdxComboboxInput]", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "combobox", "autocomplete": "off", "aria-autocomplete": "list" }, listeners: { "input": "onInput($event)", "click": "onClick($event)", "focus": "onFocus()", "blur": "onBlur()", "keydown": "onKeydown($event)", "compositionstart": "composing = true", "compositionend": "onCompositionEnd($event)" }, properties: { "attr.id": "id()", "attr.aria-haspopup": "rootContext.grid() ? \"grid\" : \"listbox\"", "attr.aria-expanded": "rootContext.open()", "attr.aria-controls": "rootContext.listId", "attr.aria-labelledby": "rootContext.labelId()", "attr.aria-activedescendant": "rootContext.activeId()", "attr.aria-describedby": "describedBy()", "attr.aria-invalid": "displayValid() === false ? \"true\" : undefined", "attr.aria-required": "requiredState() ? \"true\" : undefined", "attr.aria-disabled": "disabledState() ? \"true\" : undefined", "attr.disabled": "disabledState() ? \"\" : undefined", "attr.readonly": "rootContext.readonly() ? \"\" : undefined", "attr.required": "requiredState() ? \"\" : undefined", "value": "rootContext.inputValue()", "attr.data-popup-open": "dataAttr(rootContext.open())", "attr.data-list-empty": "dataAttr(rootContext.visibleCount() === 0)", "attr.data-placeholder": "dataAttr(isEmptyValue())", "attr.data-invalid": "dataAttr(displayValid() === false)", "attr.data-valid": "dataAttr(displayValid() === true)", "attr.data-disabled": "dataAttr(disabledState())", "attr.data-required": "dataAttr(requiredState())", "attr.data-touched": "dataAttr(touchedState())", "attr.data-dirty": "dataAttr(dirtyState())", "attr.data-filled": "dataAttr(filledState())", "attr.data-focused": "dataAttr(focusedState())" } }, exportAs: ["rdxComboboxInput"], hostDirectives: [{ directive: i1.RdxPopperAnchor }, { directive: i1$1.RdxFloatingInsideElement }], ngImport: i0 }); }
|
|
2138
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: RdxComboboxInput, isStandalone: true, selector: "input[rdxComboboxInput]", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "combobox", "autocomplete": "off", "aria-autocomplete": "list" }, listeners: { "input": "onInput($event)", "click": "onClick($event)", "focus": "onFocus()", "blur": "onBlur()", "keydown": "onKeydown($event)", "compositionstart": "composing = true", "compositionend": "onCompositionEnd($event)" }, properties: { "attr.id": "id()", "attr.aria-haspopup": "rootContext.grid() ? \"grid\" : \"listbox\"", "attr.aria-expanded": "rootContext.open()", "attr.aria-controls": "rootContext.listId", "attr.aria-labelledby": "rootContext.labelId()", "attr.aria-activedescendant": "rootContext.activeId()", "attr.aria-describedby": "describedBy()", "attr.aria-invalid": "displayValid() === false ? \"true\" : undefined", "attr.aria-required": "requiredState() ? \"true\" : undefined", "attr.aria-disabled": "disabledState() ? \"true\" : undefined", "attr.disabled": "disabledState() ? \"\" : undefined", "attr.readonly": "rootContext.readonly() ? \"\" : undefined", "attr.required": "requiredState() ? \"\" : undefined", "attr.name": "rootContext.inputOwnsFormValue() ? rootContext.name() : undefined", "attr.form": "rootContext.form()", "value": "rootContext.inputValue()", "attr.data-popup-open": "dataAttr(rootContext.open())", "attr.data-list-empty": "dataAttr(rootContext.visibleCount() === 0)", "attr.data-placeholder": "dataAttr(isEmptyValue())", "attr.data-invalid": "dataAttr(displayValid() === false)", "attr.data-valid": "dataAttr(displayValid() === true)", "attr.data-disabled": "dataAttr(disabledState())", "attr.data-required": "dataAttr(requiredState())", "attr.data-touched": "dataAttr(touchedState())", "attr.data-dirty": "dataAttr(dirtyState())", "attr.data-filled": "dataAttr(filledState())", "attr.data-focused": "dataAttr(focusedState())" } }, exportAs: ["rdxComboboxInput"], hostDirectives: [{ directive: i1.RdxPopperAnchor }, { directive: i1$1.RdxFloatingInsideElement }], ngImport: i0 }); }
|
|
1990
2139
|
}
|
|
1991
2140
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxComboboxInput, decorators: [{
|
|
1992
2141
|
type: Directive,
|
|
@@ -2011,6 +2160,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImpor
|
|
|
2011
2160
|
'[attr.disabled]': 'disabledState() ? "" : undefined',
|
|
2012
2161
|
'[attr.readonly]': 'rootContext.readonly() ? "" : undefined',
|
|
2013
2162
|
'[attr.required]': 'requiredState() ? "" : undefined',
|
|
2163
|
+
'[attr.name]': 'rootContext.inputOwnsFormValue() ? rootContext.name() : undefined',
|
|
2164
|
+
'[attr.form]': 'rootContext.form()',
|
|
2014
2165
|
'[value]': 'rootContext.inputValue()',
|
|
2015
2166
|
'[attr.data-popup-open]': 'dataAttr(rootContext.open())',
|
|
2016
2167
|
'[attr.data-list-empty]': 'dataAttr(rootContext.visibleCount() === 0)',
|