@radix-ng/primitives 1.0.0-beta.2 → 1.0.0-beta.4

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 (104) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +76 -6
  3. package/fesm2022/radix-ng-primitives-accordion.mjs +5 -3
  4. package/fesm2022/radix-ng-primitives-accordion.mjs.map +1 -1
  5. package/fesm2022/radix-ng-primitives-alert-dialog.mjs +31 -24
  6. package/fesm2022/radix-ng-primitives-alert-dialog.mjs.map +1 -1
  7. package/fesm2022/radix-ng-primitives-autocomplete.mjs +1744 -0
  8. package/fesm2022/radix-ng-primitives-autocomplete.mjs.map +1 -0
  9. package/fesm2022/radix-ng-primitives-calendar.mjs +5 -3
  10. package/fesm2022/radix-ng-primitives-calendar.mjs.map +1 -1
  11. package/fesm2022/radix-ng-primitives-combobox.mjs +1399 -606
  12. package/fesm2022/radix-ng-primitives-combobox.mjs.map +1 -1
  13. package/fesm2022/radix-ng-primitives-config.mjs +13 -4
  14. package/fesm2022/radix-ng-primitives-config.mjs.map +1 -1
  15. package/fesm2022/radix-ng-primitives-context-menu.mjs +51 -10
  16. package/fesm2022/radix-ng-primitives-context-menu.mjs.map +1 -1
  17. package/fesm2022/radix-ng-primitives-core.mjs +1345 -64
  18. package/fesm2022/radix-ng-primitives-core.mjs.map +1 -1
  19. package/fesm2022/radix-ng-primitives-date-field.mjs +5 -3
  20. package/fesm2022/radix-ng-primitives-date-field.mjs.map +1 -1
  21. package/fesm2022/radix-ng-primitives-dialog.mjs +271 -145
  22. package/fesm2022/radix-ng-primitives-dialog.mjs.map +1 -1
  23. package/fesm2022/radix-ng-primitives-direction-provider.mjs +70 -0
  24. package/fesm2022/radix-ng-primitives-direction-provider.mjs.map +1 -0
  25. package/fesm2022/radix-ng-primitives-dismissable-layer.mjs +519 -184
  26. package/fesm2022/radix-ng-primitives-dismissable-layer.mjs.map +1 -1
  27. package/fesm2022/radix-ng-primitives-drawer.mjs +154 -64
  28. package/fesm2022/radix-ng-primitives-drawer.mjs.map +1 -1
  29. package/fesm2022/radix-ng-primitives-field.mjs +3 -2
  30. package/fesm2022/radix-ng-primitives-field.mjs.map +1 -1
  31. package/fesm2022/radix-ng-primitives-floating-focus-manager.mjs +517 -0
  32. package/fesm2022/radix-ng-primitives-floating-focus-manager.mjs.map +1 -0
  33. package/fesm2022/radix-ng-primitives-focus-scope.mjs +296 -70
  34. package/fesm2022/radix-ng-primitives-focus-scope.mjs.map +1 -1
  35. package/fesm2022/radix-ng-primitives-menu.mjs +894 -299
  36. package/fesm2022/radix-ng-primitives-menu.mjs.map +1 -1
  37. package/fesm2022/radix-ng-primitives-menubar.mjs +32 -4
  38. package/fesm2022/radix-ng-primitives-menubar.mjs.map +1 -1
  39. package/fesm2022/radix-ng-primitives-navigation-menu.mjs +176 -207
  40. package/fesm2022/radix-ng-primitives-navigation-menu.mjs.map +1 -1
  41. package/fesm2022/radix-ng-primitives-popover.mjs +250 -250
  42. package/fesm2022/radix-ng-primitives-popover.mjs.map +1 -1
  43. package/fesm2022/radix-ng-primitives-popper.mjs +94 -45
  44. package/fesm2022/radix-ng-primitives-popper.mjs.map +1 -1
  45. package/fesm2022/radix-ng-primitives-portal.mjs +107 -17
  46. package/fesm2022/radix-ng-primitives-portal.mjs.map +1 -1
  47. package/fesm2022/radix-ng-primitives-presence.mjs +262 -79
  48. package/fesm2022/radix-ng-primitives-presence.mjs.map +1 -1
  49. package/fesm2022/radix-ng-primitives-preview-card.mjs +172 -218
  50. package/fesm2022/radix-ng-primitives-preview-card.mjs.map +1 -1
  51. package/fesm2022/radix-ng-primitives-roving-focus.mjs +4 -2
  52. package/fesm2022/radix-ng-primitives-roving-focus.mjs.map +1 -1
  53. package/fesm2022/radix-ng-primitives-scroll-area.mjs +5 -4
  54. package/fesm2022/radix-ng-primitives-scroll-area.mjs.map +1 -1
  55. package/fesm2022/radix-ng-primitives-select.mjs +303 -234
  56. package/fesm2022/radix-ng-primitives-select.mjs.map +1 -1
  57. package/fesm2022/radix-ng-primitives-slider.mjs +5 -3
  58. package/fesm2022/radix-ng-primitives-slider.mjs.map +1 -1
  59. package/fesm2022/radix-ng-primitives-stepper.mjs +5 -3
  60. package/fesm2022/radix-ng-primitives-stepper.mjs.map +1 -1
  61. package/fesm2022/radix-ng-primitives-time-field.mjs +5 -3
  62. package/fesm2022/radix-ng-primitives-time-field.mjs.map +1 -1
  63. package/fesm2022/radix-ng-primitives-toast.mjs +15 -36
  64. package/fesm2022/radix-ng-primitives-toast.mjs.map +1 -1
  65. package/fesm2022/radix-ng-primitives-toggle-group.mjs +5 -3
  66. package/fesm2022/radix-ng-primitives-toggle-group.mjs.map +1 -1
  67. package/fesm2022/radix-ng-primitives-toolbar.mjs +5 -3
  68. package/fesm2022/radix-ng-primitives-toolbar.mjs.map +1 -1
  69. package/fesm2022/radix-ng-primitives-tooltip.mjs +105 -145
  70. package/fesm2022/radix-ng-primitives-tooltip.mjs.map +1 -1
  71. package/package.json +14 -1
  72. package/types/radix-ng-primitives-accordion.d.ts +4 -3
  73. package/types/radix-ng-primitives-alert-dialog.d.ts +17 -11
  74. package/types/radix-ng-primitives-autocomplete.d.ts +661 -0
  75. package/types/radix-ng-primitives-calendar.d.ts +5 -3
  76. package/types/radix-ng-primitives-combobox.d.ts +727 -293
  77. package/types/radix-ng-primitives-config.d.ts +1 -1
  78. package/types/radix-ng-primitives-context-menu.d.ts +15 -5
  79. package/types/radix-ng-primitives-core.d.ts +762 -14
  80. package/types/radix-ng-primitives-date-field.d.ts +3 -2
  81. package/types/radix-ng-primitives-dialog.d.ts +107 -55
  82. package/types/radix-ng-primitives-direction-provider.d.ts +41 -0
  83. package/types/radix-ng-primitives-dismissable-layer.d.ts +147 -99
  84. package/types/radix-ng-primitives-drawer.d.ts +49 -22
  85. package/types/radix-ng-primitives-field.d.ts +1 -0
  86. package/types/radix-ng-primitives-floating-focus-manager.d.ts +175 -0
  87. package/types/radix-ng-primitives-focus-scope.d.ts +132 -1
  88. package/types/radix-ng-primitives-menu.d.ts +204 -112
  89. package/types/radix-ng-primitives-navigation-menu.d.ts +61 -101
  90. package/types/radix-ng-primitives-popover.d.ts +82 -115
  91. package/types/radix-ng-primitives-popper.d.ts +46 -10
  92. package/types/radix-ng-primitives-portal.d.ts +53 -8
  93. package/types/radix-ng-primitives-presence.d.ts +98 -17
  94. package/types/radix-ng-primitives-preview-card.d.ts +63 -95
  95. package/types/radix-ng-primitives-roving-focus.d.ts +7 -6
  96. package/types/radix-ng-primitives-scroll-area.d.ts +2 -2
  97. package/types/radix-ng-primitives-select.d.ts +192 -158
  98. package/types/radix-ng-primitives-slider.d.ts +5 -4
  99. package/types/radix-ng-primitives-stepper.d.ts +4 -3
  100. package/types/radix-ng-primitives-time-field.d.ts +3 -2
  101. package/types/radix-ng-primitives-toast.d.ts +7 -7
  102. package/types/radix-ng-primitives-toggle-group.d.ts +5 -4
  103. package/types/radix-ng-primitives-toolbar.d.ts +3 -2
  104. package/types/radix-ng-primitives-tooltip.d.ts +48 -84
@@ -0,0 +1,1744 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Directive, inject, booleanAttribute, Injector, ElementRef, model, input, computed, numberAttribute, output, signal, effect, untracked, isDevMode, ChangeDetectionStrategy, Component, afterNextRender, afterRenderEffect, DestroyRef, NgModule } from '@angular/core';
3
+ import * as i1 from '@radix-ng/primitives/combobox';
4
+ import { RdxComboboxAnchor, RdxComboboxBackdrop, useComboboxEngine, provideComboboxRootContext, injectComboboxRootContext, RdxComboboxGroup, RdxComboboxGroupLabel, RdxComboboxIcon, injectComboboxGroupContext, provideComboboxItemContext, RdxComboboxItemIndicator, RdxComboboxLabel, RdxComboboxPortal, RdxComboboxSeparator, RdxComboboxStatus, RdxComboboxTrigger } from '@radix-ng/primitives/combobox';
5
+ import * as i1$1 from '@radix-ng/primitives/popper';
6
+ import { RdxPopperArrow, RdxPopper, RdxPopperContentWrapper, provideRdxPopperContentWrapper, provideRdxPopperContentConfig, RdxPopperAnchor, injectPopperContentWrapperContext, RdxPopperContent } from '@radix-ng/primitives/popper';
7
+ import * as i1$2 from '@radix-ng/primitives/dismissable-layer';
8
+ import { RdxFloatingInsideElement, RdxDismiss } from '@radix-ng/primitives/dismissable-layer';
9
+ import { NG_VALUE_ACCESSOR } from '@angular/forms';
10
+ import * as i2 from '@radix-ng/primitives/core';
11
+ import { createFloatingRootContext, rdxDevWarning, isItemEqualToValue, itemToStringLabel, createCancelableChangeEventDetails, provideFloatingTree, provideFloatingRootContext, setupInternalBackdrop, injectId, RDX_FLOATING_ROOT_CONTEXT, RDX_FLOATING_REGISTRATION, useAnchoredScrollLock, RdxFloatingNodeRegistration, rdxDevError } from '@radix-ng/primitives/core';
12
+ import { injectDirection } from '@radix-ng/primitives/direction-provider';
13
+ import { injectFieldRootContext } from '@radix-ng/primitives/field';
14
+
15
+ /**
16
+ * Optional positioning anchor for the popup. Put it on the element the popup should align to — for
17
+ * example a wrapper that holds the input plus an icon/clear button. When present it takes precedence
18
+ * over the input. Reuses the combobox anchor behavior.
19
+ *
20
+ * @group Components
21
+ */
22
+ class RdxAutocompleteAnchor {
23
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteAnchor, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
24
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxAutocompleteAnchor, isStandalone: true, selector: "[rdxAutocompleteAnchor]", exportAs: ["rdxAutocompleteAnchor"], hostDirectives: [{ directive: i1.RdxComboboxAnchor }], ngImport: i0 }); }
25
+ }
26
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteAnchor, decorators: [{
27
+ type: Directive,
28
+ args: [{
29
+ selector: '[rdxAutocompleteAnchor]',
30
+ exportAs: 'rdxAutocompleteAnchor',
31
+ hostDirectives: [RdxComboboxAnchor]
32
+ }]
33
+ }] });
34
+
35
+ /**
36
+ * An optional arrow that points from the popup to the anchor. Composes the popper arrow directly
37
+ * (the same building block the combobox arrow uses).
38
+ *
39
+ * @group Components
40
+ */
41
+ class RdxAutocompleteArrow {
42
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteArrow, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
43
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxAutocompleteArrow, isStandalone: true, selector: "[rdxAutocompleteArrow]", exportAs: ["rdxAutocompleteArrow"], hostDirectives: [{ directive: i1$1.RdxPopperArrow, inputs: ["width", "width", "height", "height"] }], ngImport: i0 }); }
44
+ }
45
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteArrow, decorators: [{
46
+ type: Directive,
47
+ args: [{
48
+ selector: '[rdxAutocompleteArrow]',
49
+ exportAs: 'rdxAutocompleteArrow',
50
+ hostDirectives: [{ directive: RdxPopperArrow, inputs: ['width', 'height'] }]
51
+ }]
52
+ }] });
53
+
54
+ /**
55
+ * An overlay rendered beneath the popup in `modal` mode. Exposes `data-open` / `data-closed` for
56
+ * animation. Reuses the combobox backdrop.
57
+ *
58
+ * @group Components
59
+ */
60
+ class RdxAutocompleteBackdrop {
61
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteBackdrop, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
62
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxAutocompleteBackdrop, isStandalone: true, selector: "[rdxAutocompleteBackdrop]", exportAs: ["rdxAutocompleteBackdrop"], hostDirectives: [{ directive: i1.RdxComboboxBackdrop }], ngImport: i0 }); }
63
+ }
64
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteBackdrop, decorators: [{
65
+ type: Directive,
66
+ args: [{
67
+ selector: '[rdxAutocompleteBackdrop]',
68
+ exportAs: 'rdxAutocompleteBackdrop',
69
+ hostDirectives: [RdxComboboxBackdrop]
70
+ }]
71
+ }] });
72
+
73
+ // The engine stays private to the root; the context factory (a free function) reads it through this registry.
74
+ const engineRegistry = new WeakMap();
75
+ /**
76
+ * Builds the {@link RdxComboboxRootContext} the autocomplete parts consume. Autocomplete reuses the
77
+ * combobox parts (List, Popup, Positioner, Item, …) verbatim, so it provides the exact combobox context
78
+ * shape — configured for a single-value, `selectionMode: 'none'` control whose value **is** the input
79
+ * string. The shared engine supplies registry / filtering / highlight / inline; the root supplies the
80
+ * string-value semantics. Autocomplete-specific parts (mode, inline, grid) inject {@link RdxAutocompleteRoot}.
81
+ */
82
+ const context = () => {
83
+ const root = inject(RdxAutocompleteRoot);
84
+ const engine = engineRegistry.get(root);
85
+ return {
86
+ listId: engine.listId,
87
+ labelId: engine.labelId,
88
+ setLabelId: (id) => engine.setLabelId(id),
89
+ dir: root.dir,
90
+ value: root.value,
91
+ inputValue: root.value,
92
+ open: root.open,
93
+ present: root.present,
94
+ multiple: root.alwaysFalse,
95
+ selectionMode: root.noneMode,
96
+ disabledState: root.disabledState,
97
+ readonly: root.readOnly,
98
+ requiredState: root.requiredState,
99
+ openOnInputClick: root.openOnInputClick,
100
+ modal: root.modal,
101
+ virtualized: root.virtualized,
102
+ grid: root.grid,
103
+ filteredItems: engine.filteredItems,
104
+ highlightedItem: engine.highlightedItem,
105
+ highlightedIndex: engine.highlightedIndex,
106
+ activeId: engine.activeId,
107
+ itemId: (index) => engine.itemId(index),
108
+ isKeyboardActive: () => engine.isKeyboardActive(),
109
+ setKeyboardActive: (value) => engine.setKeyboardActive(value),
110
+ transitionStatus: engine.transitionStatus,
111
+ registerTransitionElement: engine.registerTransitionElement,
112
+ visibleCount: engine.visibleCount,
113
+ isVisible: (item) => engine.isVisible(item),
114
+ isSelected: (value) => root.isSelectedValue(value),
115
+ registerItem: (item) => engine.registerItem(item),
116
+ unregisterItem: (item) => engine.unregisterItem(item),
117
+ highlight: engine.highlight,
118
+ highlightNext: () => engine.highlightNext('keyboard'),
119
+ highlightPrevious: () => engine.highlightPrevious('keyboard'),
120
+ highlightNextColumn: () => engine.highlightNextColumn('keyboard'),
121
+ highlightPreviousColumn: () => engine.highlightPreviousColumn('keyboard'),
122
+ highlightFirst: () => engine.highlightFirst('keyboard'),
123
+ highlightLast: () => engine.highlightLast('keyboard'),
124
+ highlightIndex: (index, reason) => engine.highlightIndex(index, reason),
125
+ setHighlight: (item, reason) => engine.setHighlight(item, reason),
126
+ clearHighlight: () => engine.clearHighlightState(),
127
+ highlightItemOnHover: root.highlightItemOnHover,
128
+ keepHighlight: root.keepHighlight,
129
+ inputElement: engine.inputElement,
130
+ setInputElement: (el) => engine.setInputElement(el),
131
+ inputLayout: engine.inputLayout,
132
+ setInputLayout: (layout) => engine.setInputLayout(layout),
133
+ openedByTouch: engine.openedByTouch,
134
+ setOpenedByTouch: (value) => engine.setOpenedByTouch(value),
135
+ popupMounted: engine.popupMounted,
136
+ setPopupMounted: (value) => engine.setPopupMounted(value),
137
+ registerTrigger: (el) => engine.setTrigger(el),
138
+ focusInput: () => engine.focusInput(),
139
+ openPopup: (reason, event) => root.setOpen(true, reason, event),
140
+ openForBrowse: (reason, event) => root.openForBrowse(reason, event),
141
+ closePopup: (revert = true, reason, event) => root.closePopup(revert, reason, event),
142
+ setInputValue: (value) => root.setQuery(value),
143
+ openAndHighlight: (edge, reason, event) => root.openAndHighlight(edge, reason, event),
144
+ navigateByKeyboard: (direction, event) => root.navigateByKeyboard(direction, event),
145
+ select: (item, event) => root.handleSelect(item, event),
146
+ selectIndex: (index, event) => root.selectIndex(index, event),
147
+ selectHighlighted: (event) => root.selectHighlighted(event),
148
+ clearSelection: () => root.clearValue(),
149
+ removeValue: () => undefined,
150
+ removeLastValue: () => undefined,
151
+ registerChipsNav: () => undefined,
152
+ focusLastChip: () => false,
153
+ labelFor: (value) => root.labelFor(value),
154
+ markAsTouched: () => root.markAsTouched()
155
+ // `value`/`inputValue` are the input string here, not `ComboboxValue`.
156
+ };
157
+ };
158
+ /**
159
+ * `autoHighlight` transform: pass `'always'` through verbatim, coerce everything else as a boolean
160
+ * attribute (so the bare `autoHighlight` attribute reads `true`). Kept as a named function (compodoc
161
+ * hangs on an inline arrow combined with union-generic `input()`).
162
+ */
163
+ function coerceAutoHighlight(value) {
164
+ return value === 'always' ? 'always' : booleanAttribute(value);
165
+ }
166
+ /**
167
+ * Root of an Autocomplete — a text input with a filtered list of suggestions. A thin configuration over
168
+ * the shared combobox engine (ADR 0014) with `selectionMode: 'none'`, so its value **is** the input
169
+ * string: typing, selecting an item, or clearing all change a single string value. Implements
170
+ * `ControlValueAccessor` (the form value is the input string).
171
+ *
172
+ * @group Components
173
+ */
174
+ class RdxAutocompleteRoot {
175
+ // --- engine-backed surface read by the parts / tests ---
176
+ get listId() {
177
+ return this.engine.listId;
178
+ }
179
+ get labelId() {
180
+ return this.engine.labelId;
181
+ }
182
+ get inputElement() {
183
+ return this.engine.inputElement;
184
+ }
185
+ setInputElement(el) {
186
+ this.engine.setInputElement(el);
187
+ }
188
+ setInputLayout(layout) {
189
+ this.engine.setInputLayout(layout);
190
+ }
191
+ setPopupMounted(value) {
192
+ this.engine.setPopupMounted(value);
193
+ }
194
+ get inputLayout() {
195
+ return this.engine.inputLayout;
196
+ }
197
+ get openedByTouch() {
198
+ return this.engine.openedByTouch;
199
+ }
200
+ get popupMounted() {
201
+ return this.engine.popupMounted;
202
+ }
203
+ get highlight() {
204
+ return this.engine.highlight;
205
+ }
206
+ get highlightedItem() {
207
+ return this.engine.highlightedItem;
208
+ }
209
+ get highlightedIndex() {
210
+ return this.engine.highlightedIndex;
211
+ }
212
+ get activeId() {
213
+ return this.engine.activeId;
214
+ }
215
+ get filteredItems() {
216
+ return this.engine.filteredItems;
217
+ }
218
+ get visibleCount() {
219
+ return this.engine.visibleCount;
220
+ }
221
+ get inlinePreview() {
222
+ return this.engine.inlinePreview;
223
+ }
224
+ get transitionStatus() {
225
+ return this.engine.transitionStatus;
226
+ }
227
+ get registerTransitionElement() {
228
+ return this.engine.registerTransitionElement;
229
+ }
230
+ get triggerElement() {
231
+ return this.engine.triggerElement;
232
+ }
233
+ constructor() {
234
+ this.injector = inject(Injector);
235
+ /** Per-popup floating root context (ADR 0015) — `open` / `triggers` / reference for the dismissal engine. */
236
+ this.floatingContext = createFloatingRootContext({
237
+ ownerDocument: inject(ElementRef).nativeElement.ownerDocument,
238
+ open: () => this.open()
239
+ });
240
+ /** The input text. This is the form value (controlled / uncontrolled via {@link defaultValue}). */
241
+ this.value = model('', ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
242
+ /** Initial input text when uncontrolled. */
243
+ this.defaultValue = input(...(ngDevMode ? [undefined, { debugName: "defaultValue" }] : /* istanbul ignore next */ []));
244
+ /** Whether the popup is open. */
245
+ this.open = model(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
246
+ /** Initial open state when uncontrolled. */
247
+ this.defaultOpen = input(false, { ...(ngDevMode ? { debugName: "defaultOpen" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
248
+ /** Filtering / inline-completion behavior. See {@link AutocompleteMode}. */
249
+ this.mode = input('list', ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
250
+ /** Text direction. */
251
+ this.dirInput = input(undefined, { ...(ngDevMode ? { debugName: "dirInput" } : /* istanbul ignore next */ {}), alias: 'dir' });
252
+ this.dir = injectDirection(this.dirInput);
253
+ /** Whether the autocomplete is disabled. */
254
+ this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
255
+ /** Whether the autocomplete is read-only. */
256
+ this.readOnly = input(false, { ...(ngDevMode ? { debugName: "readOnly" } : /* istanbul ignore next */ {}), alias: 'readOnly', transform: booleanAttribute });
257
+ /** Whether a value is required (for forms). */
258
+ this.required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
259
+ /** Whether keyboard navigation wraps at the list boundaries. */
260
+ this.loopFocus = input(true, { ...(ngDevMode ? { debugName: "loopFocus" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
261
+ /**
262
+ * Auto-highlight behavior (matches Base UI):
263
+ * - `false` (default): never auto-highlight;
264
+ * - `true` (also the bare `autoHighlight` attribute): highlight the first match as the query changes;
265
+ * - `'always'`: keep the first navigable item highlighted whenever the popup is open.
266
+ */
267
+ this.autoHighlight = input(false, { ...(ngDevMode ? { debugName: "autoHighlight" } : /* istanbul ignore next */ {}), transform: coerceAutoHighlight });
268
+ /** Resolved auto-highlight mode. */
269
+ this.autoHighlightMode = computed(() => {
270
+ const value = this.autoHighlight();
271
+ if (value === 'always') {
272
+ return 'always';
273
+ }
274
+ if (value === true) {
275
+ return 'input-change';
276
+ }
277
+ return 'off';
278
+ }, ...(ngDevMode ? [{ debugName: "autoHighlightMode" }] : /* istanbul ignore next */ []));
279
+ /** Whether moving the pointer over an item highlights it. */
280
+ this.highlightItemOnHover = input(true, { ...(ngDevMode ? { debugName: "highlightItemOnHover" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
281
+ /** Whether a pointer-driven highlight is kept when the cursor leaves the list. */
282
+ this.keepHighlight = input(false, { ...(ngDevMode ? { debugName: "keepHighlight" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
283
+ /** Whether clicking the input opens the popup. Defaults to `false` (Base UI default). */
284
+ this.openOnInputClick = input(false, { ...(ngDevMode ? { debugName: "openOnInputClick" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
285
+ /** Whether the popup is modal: locks page scroll and makes outside content inert while open. */
286
+ this.modal = input(false, { ...(ngDevMode ? { debugName: "modal" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
287
+ /** Whether selecting an item requests submit of the closest form. */
288
+ this.submitOnItemClick = input(false, { ...(ngDevMode ? { debugName: "submitOnItemClick" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
289
+ /** Whether the list is laid out as a 2D grid (enables row/column arrow navigation). */
290
+ this.grid = input(false, { ...(ngDevMode ? { debugName: "grid" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
291
+ /**
292
+ * Filter applied to items against the input query (only when {@link mode} is `'list'` / `'both'`).
293
+ * `undefined` → locale-aware contains; a function → custom `(value, query, itemToString)`; `null` →
294
+ * built-in filtering disabled.
295
+ */
296
+ this.filter = input(undefined, ...(ngDevMode ? [{ debugName: "filter" }] : /* istanbul ignore next */ []));
297
+ /** Maximum number of matching items to show. `-1` (default) means no limit. */
298
+ this.limit = input(-1, { ...(ngDevMode ? { debugName: "limit" } : /* istanbul ignore next */ {}), transform: numberAttribute });
299
+ /** The full set of item values for {@link virtualized} mode. */
300
+ this.items = input(...(ngDevMode ? [undefined, { debugName: "items" }] : /* istanbul ignore next */ []));
301
+ /** Whether the list is externally virtualized (navigation runs over {@link items} by index). */
302
+ this.virtualized = input(false, { ...(ngDevMode ? { debugName: "virtualized" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
303
+ /** How item values are compared for equality (a comparator function or an object key). Base UI prop name. */
304
+ this.isItemEqualToValue = input(...(ngDevMode ? [undefined, { debugName: "isItemEqualToValue" }] : /* istanbul ignore next */ []));
305
+ /** Converts an item value to its string label (filter text + input text on selection). */
306
+ this.itemToStringValue = input(...(ngDevMode ? [undefined, { debugName: "itemToStringValue" }] : /* istanbul ignore next */ []));
307
+ /** Emits when the input value changes (typing, selection, or clear), with the reason. */
308
+ this.onValueChange = output();
309
+ /** Emits when the popup opens or closes. */
310
+ this.onOpenChange = output();
311
+ /** Emits as the highlight moves, with the item's value, its index in {@link filteredItems}, and the reason. */
312
+ this.onItemHighlighted = output();
313
+ /** Emits after the open/close transition (including any exit animation) finishes. */
314
+ this.onOpenChangeComplete = output();
315
+ /** Constant signals exposed to the combobox context (autocomplete is always single-value). */
316
+ this.alwaysFalse = signal(false, ...(ngDevMode ? [{ debugName: "alwaysFalse" }] : /* istanbul ignore next */ []));
317
+ this.noneMode = signal('none', ...(ngDevMode ? [{ debugName: "noneMode" }] : /* istanbul ignore next */ []));
318
+ this.cvaDisabled = signal(false, ...(ngDevMode ? [{ debugName: "cvaDisabled" }] : /* istanbul ignore next */ []));
319
+ this.disabledState = computed(() => this.disabled() || this.cvaDisabled(), ...(ngDevMode ? [{ debugName: "disabledState" }] : /* istanbul ignore next */ []));
320
+ this.requiredState = computed(() => this.required(), ...(ngDevMode ? [{ debugName: "requiredState" }] : /* istanbul ignore next */ []));
321
+ this.preventUnmountOnClose = signal(false, ...(ngDevMode ? [{ debugName: "preventUnmountOnClose" }] : /* istanbul ignore next */ []));
322
+ this.present = computed(() => this.open() || this.preventUnmountOnClose(), ...(ngDevMode ? [{ debugName: "present" }] : /* istanbul ignore next */ []));
323
+ /** Whether built-in filtering applies in the current mode (`list` / `both`). */
324
+ this.filteringMode = computed(() => this.mode() === 'list' || this.mode() === 'both', ...(ngDevMode ? [{ debugName: "filteringMode" }] : /* istanbul ignore next */ []));
325
+ /** Whether inline completion applies in the current mode (`both` / `inline`). */
326
+ this.inlineMode = computed(() => this.mode() === 'both' || this.mode() === 'inline', ...(ngDevMode ? [{ debugName: "inlineMode" }] : /* istanbul ignore next */ []));
327
+ /**
328
+ * Whether the input text is a fresh user query rather than a committed selection's label. While
329
+ * `false` (just opened, or showing a committed selection), the list is unfiltered; it flips `true`
330
+ * on the first keystroke.
331
+ */
332
+ this.typed = signal(false, ...(ngDevMode ? [{ debugName: "typed" }] : /* istanbul ignore next */ []));
333
+ /** The text the user actually typed, used as the filter query. */
334
+ this.query = computed(() => (this.typed() ? (this.value() ?? '') : ''), ...(ngDevMode ? [{ debugName: "query" }] : /* istanbul ignore next */ []));
335
+ /** The shared engine: item registry, filtering, highlight navigation (grid), inline, transition. */
336
+ this.engine = useComboboxEngine({
337
+ injector: this.injector,
338
+ listIdPrefix: 'rdx-autocomplete-list-',
339
+ popupSelector: '[rdxAutocompletePopup]',
340
+ open: this.open,
341
+ query: this.query,
342
+ filteringEnabled: this.filteringMode,
343
+ loopFocus: this.loopFocus,
344
+ autoHighlightMode: this.autoHighlightMode,
345
+ virtualized: this.virtualized,
346
+ items: this.items,
347
+ filter: this.filter,
348
+ limit: this.limit,
349
+ grid: this.grid,
350
+ rowOf: (element) => element.closest('[rdxAutocompleteRow]'),
351
+ inlineMode: this.inlineMode,
352
+ itemToString: (value) => this.labelFor(value),
353
+ onItemHighlighted: (details) => this.onItemHighlighted.emit(details),
354
+ onOpenChange: () => { },
355
+ onOpenChangeComplete: (open) => this.onOpenChangeComplete.emit(open)
356
+ });
357
+ /** What the input element displays: the inline preview if any, else the committed value. */
358
+ this.displayValue = computed(() => this.engine.inlinePreview() ?? this.value() ?? '', ...(ngDevMode ? [{ debugName: "displayValue" }] : /* istanbul ignore next */ []));
359
+ engineRegistry.set(this, this.engine);
360
+ // Keep the dismissal reference in sync with the input (the anchor) so a press / focus on it counts
361
+ // as "inside" and never dismisses (ADR 0015).
362
+ effect(() => this.floatingContext.setReferenceElement(this.engine.inputElement() ?? null));
363
+ // Apply uncontrolled defaults once.
364
+ effect(() => {
365
+ const initial = this.defaultValue();
366
+ if (initial !== undefined && untracked(this.value) === '') {
367
+ this.value.set(initial);
368
+ }
369
+ });
370
+ effect(() => {
371
+ if (untracked(this.open) === false && this.defaultOpen()) {
372
+ this.open.set(true);
373
+ }
374
+ });
375
+ // Virtualized object values can't be labelled from the DOM — warn once in dev.
376
+ if (isDevMode()) {
377
+ effect(() => {
378
+ if (!this.virtualized() || this.itemToStringValue()) {
379
+ return;
380
+ }
381
+ if (this.items()?.some((value) => value !== null && typeof value === 'object')) {
382
+ rdxDevWarning('autocomplete/virtualized-item-label', '`rdxAutocompleteRoot` `virtualized` with object item values needs `itemToStringValue` ' +
383
+ 'to render correct labels; falling back to a generic label.', 'components/autocomplete');
384
+ }
385
+ });
386
+ }
387
+ }
388
+ setSuppressInline(value) {
389
+ this.engine.setSuppressInline(value);
390
+ }
391
+ /** Opens the popup for browsing (resets the query to "pristine" and selects the input text). */
392
+ openForBrowse(reason = 'none', event = new Event('autocomplete.open-change')) {
393
+ if (!this.open()) {
394
+ this.typed.set(false);
395
+ }
396
+ this.setOpen(true, reason, event);
397
+ this.engine.selectInputText();
398
+ if (this.autoHighlightMode() === 'always') {
399
+ this.engine.setPendingHighlightEdge('first');
400
+ }
401
+ }
402
+ /** Opens the popup and highlights the given edge once the list mounts. */
403
+ openAndHighlight(edge, reason = 'list-navigation', event = new Event('autocomplete.open-change')) {
404
+ if (!this.open()) {
405
+ this.typed.set(false);
406
+ }
407
+ this.setOpen(true, reason, event);
408
+ this.engine.selectInputText();
409
+ this.engine.setPendingHighlightEdge(edge);
410
+ }
411
+ /** Whether the item's value/label matches the current input value (combobox context contract). */
412
+ isSelectedValue(value) {
413
+ const current = this.value();
414
+ if (!current) {
415
+ return false;
416
+ }
417
+ return value === current || isItemEqualToValue(value, current, this.isItemEqualToValue());
418
+ }
419
+ setOpen(open, reason = 'none', event = new Event('autocomplete.open-change')) {
420
+ if (open === this.open()) {
421
+ return true;
422
+ }
423
+ if (open && (this.disabledState() || this.readOnly())) {
424
+ return false;
425
+ }
426
+ const change = this.createOpenChangeEvent(open, reason, event);
427
+ this.onOpenChange.emit(change.payload);
428
+ if (change.eventDetails.isCanceled()) {
429
+ return false;
430
+ }
431
+ this.preventUnmountOnClose.set(open ? false : change.shouldPreventUnmountOnClose());
432
+ this.open.set(open);
433
+ return true;
434
+ }
435
+ closePopup(revert = true, reason = 'none', event = new Event('autocomplete.open-change')) {
436
+ if (!this.open()) {
437
+ return;
438
+ }
439
+ if (!this.setOpen(false, reason, event)) {
440
+ return;
441
+ }
442
+ this.engine.clearHighlightState();
443
+ this.engine.clearInlinePreview();
444
+ if (revert) {
445
+ this.typed.set(false);
446
+ }
447
+ this.markAsTouched();
448
+ }
449
+ /** Updates the input text from user typing (marks it a fresh query, emits change). */
450
+ setQuery(value) {
451
+ this.commitValue(value, 'input-change');
452
+ this.typed.set(true);
453
+ // Inline modes (`both` / `inline`) implicitly highlight the first prefix match so the input can
454
+ // be inline-completed even without an explicit `autoHighlight`.
455
+ if (this.autoHighlightMode() !== 'off' || (this.inlineMode() && value.length > 0)) {
456
+ this.engine.setPendingHighlightEdge('first-match');
457
+ }
458
+ }
459
+ labelFor(value) {
460
+ const custom = this.itemToStringValue();
461
+ if (custom) {
462
+ return custom(value);
463
+ }
464
+ const item = this.engine.orderedItems().find((i) => isItemEqualToValue(i.value(), value, this.isItemEqualToValue()));
465
+ return item ? item.textValue() : itemToStringLabel(value);
466
+ }
467
+ itemId(index) {
468
+ return this.engine.itemId(index);
469
+ }
470
+ isVisible(item) {
471
+ return this.engine.isVisible(item);
472
+ }
473
+ registerItem(item) {
474
+ this.engine.registerItem(item);
475
+ }
476
+ unregisterItem(item) {
477
+ this.engine.unregisterItem(item);
478
+ }
479
+ handleSelect(item, event = new Event('autocomplete.item-press')) {
480
+ if (this.disabledState() || this.readOnly() || item.disabled()) {
481
+ return;
482
+ }
483
+ this.commitSelection(item.textValue() || this.labelFor(item.value()), event);
484
+ }
485
+ /** Selects the filtered item at `index` (virtualized mode). */
486
+ selectIndex(index, event = new Event('autocomplete.item-press')) {
487
+ if (this.disabledState() || this.readOnly()) {
488
+ return;
489
+ }
490
+ const value = this.engine.filteredItems()[index];
491
+ if (value === undefined) {
492
+ return;
493
+ }
494
+ this.commitSelection(this.labelFor(value), event);
495
+ }
496
+ /** Commits a selection: the input value becomes the item's label, the popup closes. */
497
+ commitSelection(label, event = new Event('autocomplete.item-press')) {
498
+ // Capture focus before `commitValue` emits `onValueChange`, so restoration is skipped when the
499
+ // consumer moves focus in that callback (e.g. focusing a message field after an emoji press).
500
+ const activeBefore = typeof document !== 'undefined' ? document.activeElement : null;
501
+ this.engine.clearInlinePreview();
502
+ this.commitValue(label, 'item-press');
503
+ this.typed.set(false);
504
+ this.closePopup(false, 'item-press', event);
505
+ this.engine.restoreFocusAfterSelect(activeBefore);
506
+ this.maybeSubmit();
507
+ }
508
+ maybeSubmit() {
509
+ if (this.submitOnItemClick()) {
510
+ this.engine.inputElement()?.form?.requestSubmit?.();
511
+ }
512
+ }
513
+ selectHighlighted(event = new Event('autocomplete.item-press')) {
514
+ if (this.virtualized()) {
515
+ const index = this.engine.highlightedIndex();
516
+ if (index >= 0) {
517
+ this.selectIndex(index, event);
518
+ }
519
+ return;
520
+ }
521
+ const item = this.engine.highlightedItem();
522
+ if (item) {
523
+ this.handleSelect(item, event);
524
+ }
525
+ }
526
+ // --- highlight navigation facade (delegates to the engine; grid-aware) ---
527
+ navigateByKeyboard(direction, event = new Event('autocomplete.open-change')) {
528
+ this.engine.setKeyboardActive(true);
529
+ if (!this.open()) {
530
+ this.openAndHighlight(direction === 1 ? 'first' : 'last', 'list-navigation', event);
531
+ }
532
+ else if (direction === 1) {
533
+ this.engine.highlightNext();
534
+ }
535
+ else {
536
+ this.engine.highlightPrevious();
537
+ }
538
+ }
539
+ moveDown() {
540
+ this.engine.highlightNext();
541
+ }
542
+ moveUp() {
543
+ this.engine.highlightPrevious();
544
+ }
545
+ moveRight() {
546
+ this.engine.highlightNextColumn();
547
+ }
548
+ moveLeft() {
549
+ this.engine.highlightPreviousColumn();
550
+ }
551
+ highlightFirst(reason = 'keyboard') {
552
+ this.engine.highlightFirst(reason);
553
+ }
554
+ highlightLast(reason = 'keyboard') {
555
+ this.engine.highlightLast(reason);
556
+ }
557
+ highlightIndex(index, reason) {
558
+ this.engine.highlightIndex(index, reason);
559
+ }
560
+ setHighlight(item, reason) {
561
+ this.engine.setHighlight(item, reason);
562
+ }
563
+ clearHighlightState() {
564
+ this.engine.clearHighlightState();
565
+ }
566
+ isKeyboardActive() {
567
+ return this.engine.isKeyboardActive();
568
+ }
569
+ setKeyboardActive(value) {
570
+ this.engine.setKeyboardActive(value);
571
+ }
572
+ clearValue() {
573
+ if (this.disabledState() || this.readOnly()) {
574
+ return;
575
+ }
576
+ this.commitValue('', 'input-clear');
577
+ this.typed.set(true);
578
+ this.engine.clearInlinePreview();
579
+ this.engine.clearHighlightState();
580
+ this.engine.focusInput();
581
+ }
582
+ focusInput() {
583
+ this.engine.focusInput();
584
+ }
585
+ markAsTouched() {
586
+ this.onTouched?.();
587
+ }
588
+ commitValue(value, reason) {
589
+ // Mirror combobox's guarded commit: never mutate the value while disabled or read-only
590
+ // (the input is the form value here, so Clear / item-press / typing must all be inert).
591
+ if (this.disabledState() || this.readOnly()) {
592
+ return;
593
+ }
594
+ this.value.set(value);
595
+ this.onValueChange.emit({ value, reason });
596
+ this.onChange?.(value);
597
+ }
598
+ createOpenChangeEvent(open, reason, event) {
599
+ const change = createCancelableChangeEventDetails(reason, event, this.resolveOpenChangeTrigger(event));
600
+ return {
601
+ payload: {
602
+ open,
603
+ reason,
604
+ event: change.eventDetails.event,
605
+ trigger: change.eventDetails.trigger,
606
+ eventDetails: change.eventDetails
607
+ },
608
+ eventDetails: change.eventDetails,
609
+ shouldPreventUnmountOnClose: change.shouldPreventUnmountOnClose
610
+ };
611
+ }
612
+ resolveOpenChangeTrigger(event) {
613
+ const target = event.target;
614
+ if (target instanceof HTMLElement) {
615
+ return target;
616
+ }
617
+ return this.engine.triggerElement ?? this.engine.inputElement() ?? undefined;
618
+ }
619
+ // ControlValueAccessor (the form value is the input string)
620
+ writeValue(value) {
621
+ untracked(() => this.value.set(value ?? ''));
622
+ }
623
+ registerOnChange(fn) {
624
+ this.onChange = fn;
625
+ }
626
+ registerOnTouched(fn) {
627
+ this.onTouched = fn;
628
+ }
629
+ setDisabledState(isDisabled) {
630
+ this.cvaDisabled.set(isDisabled);
631
+ }
632
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteRoot, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
633
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxAutocompleteRoot, isStandalone: true, selector: "[rdxAutocompleteRoot]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, defaultValue: { classPropertyName: "defaultValue", publicName: "defaultValue", 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 }, mode: { classPropertyName: "mode", publicName: "mode", 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 }, grid: { classPropertyName: "grid", publicName: "grid", 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 }, isItemEqualToValue: { classPropertyName: "isItemEqualToValue", publicName: "isItemEqualToValue", isSignal: true, isRequired: false, transformFunction: null }, itemToStringValue: { classPropertyName: "itemToStringValue", publicName: "itemToStringValue", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", open: "openChange", onValueChange: "onValueChange", onOpenChange: "onOpenChange", onItemHighlighted: "onItemHighlighted", onOpenChangeComplete: "onOpenChangeComplete" }, host: { properties: { "attr.data-disabled": "disabledState() ? \"\" : undefined" } }, providers: [
634
+ provideComboboxRootContext(context),
635
+ { provide: NG_VALUE_ACCESSOR, useExisting: RdxAutocompleteRoot, multi: true },
636
+ // New floating foundation (ADR 0015/0017) — the dismissal capability reads this shared context.
637
+ provideFloatingTree(),
638
+ provideFloatingRootContext(() => inject(RdxAutocompleteRoot).floatingContext)
639
+ ], exportAs: ["rdxAutocompleteRoot"], hostDirectives: [{ directive: i1$1.RdxPopper }], ngImport: i0 }); }
640
+ }
641
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteRoot, decorators: [{
642
+ type: Directive,
643
+ args: [{
644
+ selector: '[rdxAutocompleteRoot]',
645
+ exportAs: 'rdxAutocompleteRoot',
646
+ providers: [
647
+ provideComboboxRootContext(context),
648
+ { provide: NG_VALUE_ACCESSOR, useExisting: RdxAutocompleteRoot, multi: true },
649
+ // New floating foundation (ADR 0015/0017) — the dismissal capability reads this shared context.
650
+ provideFloatingTree(),
651
+ provideFloatingRootContext(() => inject(RdxAutocompleteRoot).floatingContext)
652
+ ],
653
+ hostDirectives: [RdxPopper],
654
+ host: {
655
+ '[attr.data-disabled]': 'disabledState() ? "" : undefined'
656
+ }
657
+ }]
658
+ }], 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 }] }], 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 }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", 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 }] }], grid: [{ type: i0.Input, args: [{ isSignal: true, alias: "grid", 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 }] }], isItemEqualToValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "isItemEqualToValue", required: false }] }], itemToStringValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemToStringValue", required: false }] }], onValueChange: [{ type: i0.Output, args: ["onValueChange"] }], onOpenChange: [{ type: i0.Output, args: ["onOpenChange"] }], onItemHighlighted: [{ type: i0.Output, args: ["onItemHighlighted"] }], onOpenChangeComplete: [{ type: i0.Output, args: ["onOpenChangeComplete"] }] } });
659
+
660
+ /**
661
+ * Clears the input value. Hidden when there is nothing to clear.
662
+ *
663
+ * @group Components
664
+ */
665
+ class RdxAutocompleteClear {
666
+ constructor() {
667
+ this.root = inject(RdxAutocompleteRoot);
668
+ this.isEmpty = computed(() => !this.root.value(), ...(ngDevMode ? [{ debugName: "isEmpty" }] : /* istanbul ignore next */ []));
669
+ /** Disabled when the control is disabled or read-only (clearing is a mutation). */
670
+ this.isDisabled = computed(() => this.root.disabledState() || this.root.readOnly(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
671
+ }
672
+ onClick() {
673
+ this.root.clearValue();
674
+ }
675
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteClear, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
676
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxAutocompleteClear, isStandalone: true, selector: "button[rdxAutocompleteClear]", host: { attributes: { "type": "button", "tabindex": "-1", "aria-label": "Clear" }, listeners: { "click": "onClick()" }, properties: { "hidden": "isEmpty()", "attr.disabled": "isDisabled() ? \"\" : undefined" } }, exportAs: ["rdxAutocompleteClear"], hostDirectives: [{ directive: i1$2.RdxFloatingInsideElement }], ngImport: i0 }); }
677
+ }
678
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteClear, decorators: [{
679
+ type: Directive,
680
+ args: [{
681
+ selector: 'button[rdxAutocompleteClear]',
682
+ exportAs: 'rdxAutocompleteClear',
683
+ hostDirectives: [RdxFloatingInsideElement],
684
+ host: {
685
+ type: 'button',
686
+ tabindex: '-1',
687
+ 'aria-label': 'Clear',
688
+ '[hidden]': 'isEmpty()',
689
+ '[attr.disabled]': 'isDisabled() ? "" : undefined',
690
+ '(click)': 'onClick()'
691
+ }
692
+ }]
693
+ }] });
694
+
695
+ /**
696
+ * A polite, atomic live region announcing the "no results" message. Like the combobox empty part, the
697
+ * element stays mounted and visible at all times (never hidden/unmounted) so the transition to empty is
698
+ * announced; only its projected content is rendered conditionally.
699
+ *
700
+ * @group Components
701
+ */
702
+ class RdxAutocompleteEmpty {
703
+ constructor() {
704
+ this.rootContext = injectComboboxRootContext();
705
+ /** Whether no items match the current query (drives projection of the message). */
706
+ this.isEmpty = computed(() => this.rootContext.visibleCount() === 0, ...(ngDevMode ? [{ debugName: "isEmpty" }] : /* istanbul ignore next */ []));
707
+ }
708
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteEmpty, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
709
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: RdxAutocompleteEmpty, isStandalone: true, selector: "[rdxAutocompleteEmpty]", host: { attributes: { "role": "status", "aria-live": "polite", "aria-atomic": "true" }, properties: { "attr.data-empty": "isEmpty() ? \"\" : undefined" } }, exportAs: ["rdxAutocompleteEmpty"], ngImport: i0, template: `
710
+ @if (isEmpty()) {
711
+ <ng-content />
712
+ }
713
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
714
+ }
715
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteEmpty, decorators: [{
716
+ type: Component,
717
+ args: [{
718
+ selector: '[rdxAutocompleteEmpty]',
719
+ exportAs: 'rdxAutocompleteEmpty',
720
+ changeDetection: ChangeDetectionStrategy.OnPush,
721
+ template: `
722
+ @if (isEmpty()) {
723
+ <ng-content />
724
+ }
725
+ `,
726
+ host: {
727
+ role: 'status',
728
+ 'aria-live': 'polite',
729
+ 'aria-atomic': 'true',
730
+ // Present only while the message is shown. Lets consumers collapse the always-mounted region
731
+ // (e.g. `data-[empty]:py-6`) without `display:none`/`hidden`, which would break the announcement.
732
+ '[attr.data-empty]': 'isEmpty() ? "" : undefined'
733
+ }
734
+ }]
735
+ }] });
736
+
737
+ /**
738
+ * Groups related options under a shared label. Hides itself when all of its items are filtered out.
739
+ * Reuses the combobox group (and exposes the combobox group context for the label + items).
740
+ *
741
+ * @group Components
742
+ */
743
+ class RdxAutocompleteGroup {
744
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteGroup, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
745
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxAutocompleteGroup, isStandalone: true, selector: "[rdxAutocompleteGroup]", exportAs: ["rdxAutocompleteGroup"], hostDirectives: [{ directive: i1.RdxComboboxGroup }], ngImport: i0 }); }
746
+ }
747
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteGroup, decorators: [{
748
+ type: Directive,
749
+ args: [{
750
+ selector: '[rdxAutocompleteGroup]',
751
+ exportAs: 'rdxAutocompleteGroup',
752
+ hostDirectives: [RdxComboboxGroup]
753
+ }]
754
+ }] });
755
+
756
+ /**
757
+ * Accessible label for a {@link RdxAutocompleteGroup}. Wires itself up via `aria-labelledby`. Reuses
758
+ * the combobox group label.
759
+ *
760
+ * @group Components
761
+ */
762
+ class RdxAutocompleteGroupLabel {
763
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteGroupLabel, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
764
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxAutocompleteGroupLabel, isStandalone: true, selector: "[rdxAutocompleteGroupLabel]", exportAs: ["rdxAutocompleteGroupLabel"], hostDirectives: [{ directive: i1.RdxComboboxGroupLabel }], ngImport: i0 }); }
765
+ }
766
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteGroupLabel, decorators: [{
767
+ type: Directive,
768
+ args: [{
769
+ selector: '[rdxAutocompleteGroupLabel]',
770
+ exportAs: 'rdxAutocompleteGroupLabel',
771
+ hostDirectives: [RdxComboboxGroupLabel]
772
+ }]
773
+ }] });
774
+
775
+ /**
776
+ * Decorative icon inside the trigger. Hidden from assistive technology. Reuses the combobox icon.
777
+ *
778
+ * @group Components
779
+ */
780
+ class RdxAutocompleteIcon {
781
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteIcon, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
782
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxAutocompleteIcon, isStandalone: true, selector: "[rdxAutocompleteIcon]", exportAs: ["rdxAutocompleteIcon"], hostDirectives: [{ directive: i1.RdxComboboxIcon }], ngImport: i0 }); }
783
+ }
784
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteIcon, decorators: [{
785
+ type: Directive,
786
+ args: [{
787
+ selector: '[rdxAutocompleteIcon]',
788
+ exportAs: 'rdxAutocompleteIcon',
789
+ hostDirectives: [RdxComboboxIcon]
790
+ }]
791
+ }] });
792
+
793
+ /**
794
+ * Positions the autocomplete popup relative to the input anchor using the popper engine.
795
+ *
796
+ * A "thin" positioner (ADR 0012): it inherits the full popper positioning surface — the inputs
797
+ * (`side`, `sideOffset`, `align`, …), the `placed` output, and the host bindings — from
798
+ * {@link RdxPopperContentWrapper}, and only declares autocomplete's Base UI-aligned defaults through
799
+ * the config provider (the same building block the combobox positioner uses).
800
+ *
801
+ * @group Components
802
+ */
803
+ class RdxAutocompletePositioner extends RdxPopperContentWrapper {
804
+ constructor() {
805
+ super();
806
+ const root = inject(RdxAutocompleteRoot);
807
+ const injector = inject(Injector);
808
+ const host = inject(ElementRef).nativeElement;
809
+ // A modal autocomplete isolates the background with an internal backdrop (Base UI); the input stays
810
+ // clickable through a cutout. (Autocomplete is non-modal by default — usually no backdrop.)
811
+ afterNextRender(() => setupInternalBackdrop(host, injector, {
812
+ isOpen: () => root.open(),
813
+ shouldRender: () => root.modal(),
814
+ cutout: () => root.inputElement() ?? null
815
+ }));
816
+ }
817
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompletePositioner, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
818
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxAutocompletePositioner, isStandalone: true, selector: "[rdxAutocompletePositioner]", providers: [
819
+ ...provideRdxPopperContentWrapper(RdxAutocompletePositioner),
820
+ provideRdxPopperContentConfig({ sideOffset: 4, align: 'start' })
821
+ ], exportAs: ["rdxAutocompletePositioner"], usesInheritance: true, ngImport: i0 }); }
822
+ }
823
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompletePositioner, decorators: [{
824
+ type: Directive,
825
+ args: [{
826
+ selector: '[rdxAutocompletePositioner]',
827
+ exportAs: 'rdxAutocompletePositioner',
828
+ providers: [
829
+ ...provideRdxPopperContentWrapper(RdxAutocompletePositioner),
830
+ provideRdxPopperContentConfig({ sideOffset: 4, align: 'start' })
831
+ ]
832
+ }]
833
+ }], ctorParameters: () => [] });
834
+
835
+ const attr$1 = (value) => (value ? '' : undefined);
836
+ /**
837
+ * The autocomplete text input. Holds DOM focus at all times; the highlighted option is referenced via
838
+ * `aria-activedescendant`. In `both` / `inline` modes it shows the active item's inline completion
839
+ * with the completed suffix selected. Integrates with Field for labeling and validation state.
840
+ *
841
+ * @group Components
842
+ */
843
+ class RdxAutocompleteInput {
844
+ constructor() {
845
+ this.root = inject(RdxAutocompleteRoot);
846
+ this.element = inject(ElementRef).nativeElement;
847
+ this.fieldRootContext = injectFieldRootContext(true);
848
+ /** The input id; Field labels and descriptions reference it for accessible relationships. */
849
+ this.id = input(injectId('rdx-autocomplete-input-'), ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
850
+ /** Marks the input as invalid independently of any Field state. */
851
+ this.invalid = input(false, { ...(ngDevMode ? { debugName: "invalid" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
852
+ // Mirrors the configured mode (matches Base UI): 'list' | 'both' | 'inline' | 'none' — all valid
853
+ // `aria-autocomplete` tokens. Must reflect the static mechanism, not the transient inline preview.
854
+ this.ariaAutocomplete = computed(() => this.root.mode(), ...(ngDevMode ? [{ debugName: "ariaAutocomplete" }] : /* istanbul ignore next */ []));
855
+ this.invalidState = computed(() => this.invalid() || Boolean(this.fieldRootContext?.invalidState()), ...(ngDevMode ? [{ debugName: "invalidState" }] : /* istanbul ignore next */ []));
856
+ this.disabledState = computed(() => this.root.disabledState() || Boolean(this.fieldRootContext?.disabledState()), ...(ngDevMode ? [{ debugName: "disabledState" }] : /* istanbul ignore next */ []));
857
+ this.requiredState = computed(() => this.root.requiredState() || Boolean(this.fieldRootContext?.requiredState()), ...(ngDevMode ? [{ debugName: "requiredState" }] : /* istanbul ignore next */ []));
858
+ this.filledState = computed(() => Boolean(this.root.value()) || Boolean(this.fieldRootContext?.filledState()), ...(ngDevMode ? [{ debugName: "filledState" }] : /* istanbul ignore next */ []));
859
+ this.focusedState = computed(() => Boolean(this.fieldRootContext?.focusedState()), ...(ngDevMode ? [{ debugName: "focusedState" }] : /* istanbul ignore next */ []));
860
+ this.describedBy = computed(() => {
861
+ if (!this.fieldRootContext) {
862
+ return undefined;
863
+ }
864
+ const ids = [
865
+ ...this.fieldRootContext.descriptionIds(),
866
+ ...(this.fieldRootContext.invalidState() ? this.fieldRootContext.errorIds() : [])
867
+ ];
868
+ return ids.length ? ids.join(' ') : undefined;
869
+ }, ...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));
870
+ /** Whether an IME composition is in progress (CJK). While composing, don't filter or select. */
871
+ this.composing = false;
872
+ this.dataAttr = attr$1;
873
+ this.root.setInputElement(this.element);
874
+ // Report the layout (Base UI's `inputInsidePopup`): a positioner ancestor means the input lives
875
+ // inside the popup, so the Trigger becomes the focusable `role="combobox"`; otherwise the input
876
+ // is the tab stop and the Trigger is a `tabindex="-1"` toggle.
877
+ this.root.setInputLayout(inject(RdxAutocompletePositioner, { optional: true }) ? 'inside' : 'outside');
878
+ afterNextRender(() => {
879
+ this.fieldRootContext?.setControlId(this.id());
880
+ });
881
+ // Select the completed part of an inline preview so the next keystroke replaces it: the suffix
882
+ // after the typed prefix when the label prefix-matches, otherwise the whole navigated label.
883
+ afterRenderEffect(() => {
884
+ const preview = this.root.inlinePreview();
885
+ if (preview === null) {
886
+ return;
887
+ }
888
+ const query = this.root.query();
889
+ const start = query && preview.toLowerCase().startsWith(query.toLowerCase()) ? query.length : 0;
890
+ this.element.setSelectionRange(start, preview.length);
891
+ });
892
+ inject(DestroyRef).onDestroy(() => {
893
+ if (this.root.inputElement() === this.element) {
894
+ this.root.setInputElement(null);
895
+ }
896
+ });
897
+ }
898
+ onInput(event) {
899
+ if (this.composing || event.isComposing) {
900
+ return;
901
+ }
902
+ this.commitInput(event.target.value, event);
903
+ }
904
+ onCompositionEnd(event) {
905
+ this.composing = false;
906
+ this.commitInput(event.target.value, event);
907
+ }
908
+ commitInput(value, event) {
909
+ // Base UI opens on input only for a non-empty trimmed value — whitespace alone won't open it.
910
+ if (!this.root.open() && value.trim() !== '') {
911
+ this.root.setOpen(true, 'input-change', event);
912
+ }
913
+ this.root.setQuery(value);
914
+ }
915
+ onClick(event) {
916
+ if (this.root.openOnInputClick()) {
917
+ this.root.openForBrowse('input-press', event);
918
+ }
919
+ }
920
+ onFocus() {
921
+ this.fieldRootContext?.setFocused(true);
922
+ }
923
+ onBlur() {
924
+ this.fieldRootContext?.setFocused(false);
925
+ this.fieldRootContext?.setTouched(true);
926
+ }
927
+ onKeydown(event) {
928
+ if (event.isComposing || this.composing) {
929
+ return;
930
+ }
931
+ // Backspace / Delete must never re-add an inline completion for the resulting edit.
932
+ this.root.setSuppressInline(event.key === 'Backspace' || event.key === 'Delete');
933
+ if (event.ctrlKey || event.metaKey || event.altKey || event.shiftKey) {
934
+ return;
935
+ }
936
+ const open = this.root.open();
937
+ switch (event.key) {
938
+ case 'ArrowDown':
939
+ event.preventDefault();
940
+ this.root.setKeyboardActive(true);
941
+ if (!open) {
942
+ this.root.openAndHighlight('first', 'list-navigation', event);
943
+ }
944
+ else {
945
+ this.root.moveDown();
946
+ }
947
+ break;
948
+ case 'ArrowUp':
949
+ event.preventDefault();
950
+ this.root.setKeyboardActive(true);
951
+ if (!open) {
952
+ this.root.openAndHighlight('last', 'list-navigation', event);
953
+ }
954
+ else {
955
+ this.root.moveUp();
956
+ }
957
+ break;
958
+ case 'ArrowRight':
959
+ if (open && this.root.grid()) {
960
+ event.preventDefault();
961
+ this.root.setKeyboardActive(true);
962
+ this.root.moveRight();
963
+ }
964
+ break;
965
+ case 'ArrowLeft':
966
+ if (open && this.root.grid()) {
967
+ event.preventDefault();
968
+ this.root.setKeyboardActive(true);
969
+ this.root.moveLeft();
970
+ }
971
+ break;
972
+ case 'Home':
973
+ // In a grid the search box is a filter, so Home/End jump to the first/last cell rather
974
+ // than moving the caret (outside a grid they keep their native text-editing behavior).
975
+ if (open && this.root.grid()) {
976
+ event.preventDefault();
977
+ this.root.setKeyboardActive(true);
978
+ this.root.highlightFirst();
979
+ }
980
+ break;
981
+ case 'End':
982
+ if (open && this.root.grid()) {
983
+ event.preventDefault();
984
+ this.root.setKeyboardActive(true);
985
+ this.root.highlightLast();
986
+ }
987
+ break;
988
+ case 'Enter':
989
+ if (open) {
990
+ const hasHighlight = this.root.virtualized()
991
+ ? this.root.highlightedIndex() >= 0
992
+ : this.root.highlightedItem() !== null;
993
+ if (hasHighlight) {
994
+ event.preventDefault();
995
+ this.root.selectHighlighted(event);
996
+ }
997
+ else if (!this.root.inlineMode()) {
998
+ // Non-inline: close and let native form submission proceed. Inline modes keep the
999
+ // popup open on Enter without a highlight (matches Base UI).
1000
+ this.root.closePopup(true, 'none', event);
1001
+ }
1002
+ }
1003
+ break;
1004
+ case 'Escape':
1005
+ if (open) {
1006
+ event.preventDefault();
1007
+ this.root.closePopup(true, 'escape-key', event);
1008
+ }
1009
+ else if (!this.root.popupMounted()) {
1010
+ // Base UI: Escape on a closed autocomplete clears the input value (a no-op while
1011
+ // read-only / disabled). Guard on `popupMounted` so the same Escape that just closed
1012
+ // an open popup (the `open` branch above) doesn't also clear.
1013
+ this.root.clearValue();
1014
+ }
1015
+ break;
1016
+ case 'Tab':
1017
+ // Tab dismisses a real popup and lets focus move on. With no popup (the always-open,
1018
+ // inline "command palette" layout), Tab must NOT close — it just moves focus within the
1019
+ // surrounding dialog. Guard on `popupMounted` so closing doesn't tear down that dialog.
1020
+ if (open && this.root.popupMounted()) {
1021
+ this.root.closePopup(true, 'none', event);
1022
+ }
1023
+ break;
1024
+ }
1025
+ }
1026
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteInput, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1027
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxAutocompleteInput, isStandalone: true, selector: "input[rdxAutocompleteInput]", 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" }, listeners: { "input": "onInput($event)", "click": "onClick($event)", "focus": "onFocus()", "blur": "onBlur()", "keydown": "onKeydown($event)", "compositionstart": "composing = true", "compositionend": "onCompositionEnd($event)" }, properties: { "attr.aria-autocomplete": "ariaAutocomplete()", "attr.id": "id()", "attr.aria-haspopup": "root.grid() ? \"grid\" : \"listbox\"", "attr.aria-expanded": "root.open()", "attr.aria-controls": "root.listId", "attr.aria-labelledby": "root.labelId()", "attr.aria-activedescendant": "root.activeId()", "attr.aria-describedby": "describedBy()", "attr.aria-invalid": "invalidState() ? \"true\" : undefined", "attr.aria-required": "requiredState() ? \"true\" : undefined", "attr.aria-disabled": "disabledState() ? \"true\" : undefined", "attr.disabled": "disabledState() ? \"\" : undefined", "attr.readonly": "root.readOnly() ? \"\" : undefined", "attr.required": "requiredState() ? \"\" : undefined", "value": "root.displayValue()", "attr.data-popup-open": "dataAttr(root.open())", "attr.data-list-empty": "dataAttr(root.visibleCount() === 0)", "attr.data-invalid": "dataAttr(invalidState())", "attr.data-valid": "dataAttr(!invalidState())", "attr.data-disabled": "dataAttr(disabledState())", "attr.data-required": "dataAttr(requiredState())", "attr.data-filled": "dataAttr(filledState())", "attr.data-focused": "dataAttr(focusedState())" } }, exportAs: ["rdxAutocompleteInput"], hostDirectives: [{ directive: i1$1.RdxPopperAnchor }, { directive: i1$2.RdxFloatingInsideElement }], ngImport: i0 }); }
1028
+ }
1029
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteInput, decorators: [{
1030
+ type: Directive,
1031
+ args: [{
1032
+ selector: 'input[rdxAutocompleteInput]',
1033
+ exportAs: 'rdxAutocompleteInput',
1034
+ hostDirectives: [RdxPopperAnchor, RdxFloatingInsideElement],
1035
+ host: {
1036
+ role: 'combobox',
1037
+ autocomplete: 'off',
1038
+ '[attr.aria-autocomplete]': 'ariaAutocomplete()',
1039
+ '[attr.id]': 'id()',
1040
+ '[attr.aria-haspopup]': 'root.grid() ? "grid" : "listbox"',
1041
+ '[attr.aria-expanded]': 'root.open()',
1042
+ '[attr.aria-controls]': 'root.listId',
1043
+ '[attr.aria-labelledby]': 'root.labelId()',
1044
+ '[attr.aria-activedescendant]': 'root.activeId()',
1045
+ '[attr.aria-describedby]': 'describedBy()',
1046
+ '[attr.aria-invalid]': 'invalidState() ? "true" : undefined',
1047
+ '[attr.aria-required]': 'requiredState() ? "true" : undefined',
1048
+ '[attr.aria-disabled]': 'disabledState() ? "true" : undefined',
1049
+ '[attr.disabled]': 'disabledState() ? "" : undefined',
1050
+ '[attr.readonly]': 'root.readOnly() ? "" : undefined',
1051
+ '[attr.required]': 'requiredState() ? "" : undefined',
1052
+ '[value]': 'root.displayValue()',
1053
+ '[attr.data-popup-open]': 'dataAttr(root.open())',
1054
+ '[attr.data-list-empty]': 'dataAttr(root.visibleCount() === 0)',
1055
+ '[attr.data-invalid]': 'dataAttr(invalidState())',
1056
+ '[attr.data-valid]': 'dataAttr(!invalidState())',
1057
+ '[attr.data-disabled]': 'dataAttr(disabledState())',
1058
+ '[attr.data-required]': 'dataAttr(requiredState())',
1059
+ '[attr.data-filled]': 'dataAttr(filledState())',
1060
+ '[attr.data-focused]': 'dataAttr(focusedState())',
1061
+ '(input)': 'onInput($event)',
1062
+ '(click)': 'onClick($event)',
1063
+ '(focus)': 'onFocus()',
1064
+ '(blur)': 'onBlur()',
1065
+ '(keydown)': 'onKeydown($event)',
1066
+ '(compositionstart)': 'composing = true',
1067
+ '(compositionend)': 'onCompositionEnd($event)'
1068
+ }
1069
+ }]
1070
+ }], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }] } });
1071
+
1072
+ const attr = (value) => (value ? '' : undefined);
1073
+ /**
1074
+ * Optional wrapper around the input and its adornments (icon, clear, trigger). Mirrors the input's
1075
+ * state via `data-*` so the whole group can be styled together (focus ring, disabled, etc.).
1076
+ *
1077
+ * @group Components
1078
+ */
1079
+ class RdxAutocompleteInputGroup {
1080
+ constructor() {
1081
+ this.root = inject(RdxAutocompleteRoot);
1082
+ this.dataAttr = attr;
1083
+ }
1084
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteInputGroup, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1085
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxAutocompleteInputGroup, isStandalone: true, selector: "[rdxAutocompleteInputGroup]", host: { properties: { "attr.data-popup-open": "dataAttr(root.open())", "attr.data-disabled": "dataAttr(root.disabledState())", "attr.data-required": "dataAttr(root.requiredState())", "attr.data-filled": "dataAttr(!!root.value())" } }, exportAs: ["rdxAutocompleteInputGroup"], ngImport: i0 }); }
1086
+ }
1087
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteInputGroup, decorators: [{
1088
+ type: Directive,
1089
+ args: [{
1090
+ selector: '[rdxAutocompleteInputGroup]',
1091
+ exportAs: 'rdxAutocompleteInputGroup',
1092
+ host: {
1093
+ '[attr.data-popup-open]': 'dataAttr(root.open())',
1094
+ '[attr.data-disabled]': 'dataAttr(root.disabledState())',
1095
+ '[attr.data-required]': 'dataAttr(root.requiredState())',
1096
+ '[attr.data-filled]': 'dataAttr(!!root.value())'
1097
+ }
1098
+ }]
1099
+ }] });
1100
+
1101
+ /**
1102
+ * A row in a grid-layout autocomplete list. Groups the items in one row so the root can navigate by
1103
+ * row (ArrowUp / ArrowDown) and within a row (ArrowLeft / ArrowRight). Only meaningful when the root
1104
+ * has `grid` enabled; the root resolves an item's row from its nearest `[rdxAutocompleteRow]` ancestor.
1105
+ *
1106
+ * @group Components
1107
+ */
1108
+ class RdxAutocompleteRow {
1109
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteRow, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1110
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxAutocompleteRow, isStandalone: true, selector: "[rdxAutocompleteRow]", host: { attributes: { "role": "row" } }, exportAs: ["rdxAutocompleteRow"], ngImport: i0 }); }
1111
+ }
1112
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteRow, decorators: [{
1113
+ type: Directive,
1114
+ args: [{
1115
+ selector: '[rdxAutocompleteRow]',
1116
+ exportAs: 'rdxAutocompleteRow',
1117
+ host: {
1118
+ role: 'row'
1119
+ }
1120
+ }]
1121
+ }] });
1122
+
1123
+ const itemContext = () => {
1124
+ const item = inject(RdxAutocompleteItem);
1125
+ return {
1126
+ isSelected: item.isSelected,
1127
+ isHighlighted: item.isHighlighted,
1128
+ disabled: item.disabled,
1129
+ value: item.value
1130
+ };
1131
+ };
1132
+ /**
1133
+ * A selectable suggestion. Registers itself with the root for filtering and navigation. Highlight is
1134
+ * virtual (`data-highlighted` + `aria-activedescendant` on the input) — items never take DOM focus.
1135
+ * Selecting an item writes its text into the input. Unlike the combobox item, the `value` is optional;
1136
+ * when omitted, selection falls back to the option's text content (autocomplete's value is the input string).
1137
+ *
1138
+ * @group Components
1139
+ */
1140
+ class RdxAutocompleteItem {
1141
+ constructor() {
1142
+ this.rootContext = injectComboboxRootContext();
1143
+ this.element = inject(ElementRef).nativeElement;
1144
+ this.id = injectId('rdx-autocomplete-item-');
1145
+ /**
1146
+ * The explicit `[value]`, or `undefined` when omitted. Read the resolved {@link value} instead —
1147
+ * it falls back to the text content only when no value was bound (so explicit falsy values like
1148
+ * `0` / `''` / `null` are preserved for the filter and selection).
1149
+ */
1150
+ this.valueInput = input(undefined, { ...(ngDevMode ? { debugName: "valueInput" } : /* istanbul ignore next */ {}), alias: 'value' });
1151
+ /** Explicit text matched against the query and written to the input. Defaults to text content. */
1152
+ this.textValueInput = input('', { ...(ngDevMode ? { debugName: "textValueInput" } : /* istanbul ignore next */ {}), alias: 'textValue' });
1153
+ /** Whether the option is disabled. */
1154
+ this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1155
+ /** The option's index in the list. Required in virtualized mode. */
1156
+ this.index = input(...(ngDevMode ? [undefined, { debugName: "index" }] : /* istanbul ignore next */ []));
1157
+ this.virtualized = this.rootContext.virtualized;
1158
+ this.autoTextValue = signal('', ...(ngDevMode ? [{ debugName: "autoTextValue" }] : /* istanbul ignore next */ []));
1159
+ this.textValue = computed(() => this.textValueInput() || this.autoTextValue(), ...(ngDevMode ? [{ debugName: "textValue" }] : /* istanbul ignore next */ []));
1160
+ /**
1161
+ * The option's effective value: the explicit `[value]` if bound (preserving `0` / `''` / `null`),
1162
+ * otherwise the text content (autocomplete's value is the input string). Only an absent input —
1163
+ * `undefined` — falls back, so a custom filter still sees the real `itemValue` for falsy values.
1164
+ */
1165
+ this.value = computed(() => {
1166
+ const bound = this.valueInput();
1167
+ return bound === undefined ? this.textValue() : bound;
1168
+ }, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
1169
+ this.elementId = computed(() => this.virtualized() ? this.rootContext.itemId(this.index() ?? -1) : this.id, ...(ngDevMode ? [{ debugName: "elementId" }] : /* istanbul ignore next */ []));
1170
+ this.ariaSetSize = computed(() => this.virtualized() ? this.rootContext.filteredItems().length : undefined, ...(ngDevMode ? [{ debugName: "ariaSetSize" }] : /* istanbul ignore next */ []));
1171
+ this.ariaPosInSet = computed(() => (this.virtualized() ? (this.index() ?? -1) + 1 : undefined), ...(ngDevMode ? [{ debugName: "ariaPosInSet" }] : /* istanbul ignore next */ []));
1172
+ /** The nearest enclosing grid row, if any (drives the `gridcell` role). */
1173
+ this.row = inject(RdxAutocompleteRow, { optional: true });
1174
+ /** `gridcell` only when actually inside a `RdxAutocompleteRow` of a grid list; otherwise `option`. */
1175
+ this.role = computed(() => (this.rootContext.grid() && this.row ? 'gridcell' : 'option'), ...(ngDevMode ? [{ debugName: "role" }] : /* istanbul ignore next */ []));
1176
+ this.isVisible = computed(() => (this.virtualized() ? true : this.rootContext.isVisible(this)), ...(ngDevMode ? [{ debugName: "isVisible" }] : /* istanbul ignore next */ []));
1177
+ this.isSelected = computed(() => this.rootContext.isSelected(this.value()), ...(ngDevMode ? [{ debugName: "isSelected" }] : /* istanbul ignore next */ []));
1178
+ this.isHighlighted = computed(() => this.virtualized()
1179
+ ? this.rootContext.highlightedIndex() === this.index()
1180
+ : this.rootContext.highlightedItem() === this, ...(ngDevMode ? [{ debugName: "isHighlighted" }] : /* istanbul ignore next */ []));
1181
+ this.group = injectComboboxGroupContext(true);
1182
+ // Whether a primary-button pointerdown started on **this** item. A normal press+release here is
1183
+ // committed by `click`; `mouseup` is only the drag-end fallback for a press that began *elsewhere*.
1184
+ this.pointerDownStarted = false;
1185
+ const destroyRef = inject(DestroyRef);
1186
+ afterNextRender(() => {
1187
+ if (this.virtualized()) {
1188
+ return;
1189
+ }
1190
+ if (!this.textValueInput()) {
1191
+ const clone = this.element.cloneNode(true);
1192
+ clone.querySelectorAll('[rdxAutocompleteItemIndicator]').forEach((node) => node.remove());
1193
+ this.autoTextValue.set(clone.textContent?.trim() ?? '');
1194
+ }
1195
+ this.rootContext.registerItem(this);
1196
+ this.group?.registerItem(this);
1197
+ });
1198
+ destroyRef.onDestroy(() => {
1199
+ if (this.virtualized()) {
1200
+ return;
1201
+ }
1202
+ this.rootContext.unregisterItem(this);
1203
+ this.group?.unregisterItem(this);
1204
+ });
1205
+ // Keep the highlighted option in view while navigating a scrollable popup. `block: 'nearest'`
1206
+ // makes hover a no-op (the item is already visible) and only scrolls on keyboard navigation.
1207
+ afterRenderEffect(() => {
1208
+ if (!this.virtualized() && this.isHighlighted()) {
1209
+ this.element.scrollIntoView({ block: 'nearest' });
1210
+ }
1211
+ });
1212
+ // Reset the press flag whenever the popup closes (matches Base UI), so a later drag-end onto
1213
+ // this item isn't blocked by a stale press from an earlier interaction.
1214
+ effect(() => {
1215
+ if (!this.rootContext.open()) {
1216
+ this.pointerDownStarted = false;
1217
+ }
1218
+ });
1219
+ }
1220
+ onPointerDown(event) {
1221
+ if (event.button !== 0) {
1222
+ return;
1223
+ }
1224
+ event.preventDefault();
1225
+ this.rootContext.setKeyboardActive(false);
1226
+ this.pointerDownStarted = true;
1227
+ }
1228
+ onMouseDown(event) {
1229
+ // Belt-and-suspenders for keeping focus on the input (and iOS Safari blur on tap).
1230
+ if (event.button === 0) {
1231
+ event.preventDefault();
1232
+ }
1233
+ }
1234
+ onMouseUp(event) {
1235
+ // Read-and-reset the press flag first (matches Base UI), so a press+release here doesn't leave
1236
+ // it set and block a later drag-end onto this same item. Drag-end: commit when the primary
1237
+ // button is released over the highlighted item while the press began on a *different* element
1238
+ // (so `click` won't fire here). A press that began on this item is committed by `click` instead.
1239
+ const startedHere = this.pointerDownStarted;
1240
+ this.pointerDownStarted = false;
1241
+ if (event.button !== 0 || startedHere || !this.isHighlighted()) {
1242
+ return;
1243
+ }
1244
+ this.commitSelection();
1245
+ }
1246
+ onClick() {
1247
+ // Primary selection trigger; also fires for programmatic `.click()`.
1248
+ this.commitSelection();
1249
+ }
1250
+ commitSelection() {
1251
+ if (this.virtualized()) {
1252
+ this.rootContext.selectIndex(this.index() ?? -1);
1253
+ }
1254
+ else {
1255
+ this.rootContext.select(this);
1256
+ }
1257
+ }
1258
+ onPointerMove() {
1259
+ // Hover highlighting disabled: leave `data-highlighted` to keyboard/auto-highlight only.
1260
+ if (!this.rootContext.highlightItemOnHover()) {
1261
+ return;
1262
+ }
1263
+ if (this.rootContext.isKeyboardActive()) {
1264
+ this.rootContext.setKeyboardActive(false);
1265
+ return;
1266
+ }
1267
+ if (this.disabled()) {
1268
+ return;
1269
+ }
1270
+ if (this.virtualized()) {
1271
+ this.rootContext.highlightIndex(this.index() ?? -1, 'pointer');
1272
+ }
1273
+ else if (this.isVisible()) {
1274
+ this.rootContext.setHighlight(this, 'pointer');
1275
+ }
1276
+ }
1277
+ // Clear a pointer-driven highlight when the cursor leaves the list (unless `keepHighlight`).
1278
+ // Moving to another element inside the list keeps it (the next item's move re-highlights).
1279
+ onPointerLeave(event) {
1280
+ if (event.pointerType === 'touch' ||
1281
+ !this.rootContext.open() ||
1282
+ !this.rootContext.highlightItemOnHover() ||
1283
+ this.rootContext.keepHighlight()) {
1284
+ return;
1285
+ }
1286
+ const related = event.relatedTarget;
1287
+ const list = related && document.getElementById(this.rootContext.listId);
1288
+ if (list && list.contains(related)) {
1289
+ return;
1290
+ }
1291
+ this.rootContext.clearHighlight();
1292
+ }
1293
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteItem, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1294
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxAutocompleteItem, isStandalone: true, selector: "[rdxAutocompleteItem]", inputs: { valueInput: { classPropertyName: "valueInput", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, textValueInput: { classPropertyName: "textValueInput", publicName: "textValue", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, index: { classPropertyName: "index", publicName: "index", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "pointerdown": "onPointerDown($event)", "mousedown": "onMouseDown($event)", "mouseup": "onMouseUp($event)", "click": "onClick()", "pointermove": "onPointerMove()", "pointerleave": "onPointerLeave($event)" }, properties: { "attr.role": "role()", "attr.id": "elementId()", "attr.aria-disabled": "disabled() ? \"true\" : undefined", "attr.aria-setsize": "ariaSetSize()", "attr.aria-posinset": "ariaPosInSet()", "attr.data-highlighted": "isHighlighted() ? \"\" : undefined", "attr.data-disabled": "disabled() ? \"\" : undefined", "hidden": "!isVisible()", "attr.data-hidden": "isVisible() ? undefined : \"\"" } }, providers: [provideComboboxItemContext(itemContext)], exportAs: ["rdxAutocompleteItem"], ngImport: i0 }); }
1295
+ }
1296
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteItem, decorators: [{
1297
+ type: Directive,
1298
+ args: [{
1299
+ selector: '[rdxAutocompleteItem]',
1300
+ exportAs: 'rdxAutocompleteItem',
1301
+ providers: [provideComboboxItemContext(itemContext)],
1302
+ host: {
1303
+ '[attr.role]': 'role()',
1304
+ '[attr.id]': 'elementId()',
1305
+ // Autocomplete is always `selectionMode="none"`, so options carry no selection state: Base UI
1306
+ // omits `aria-selected` / `data-selected` here entirely (rather than rendering `false`).
1307
+ '[attr.aria-disabled]': 'disabled() ? "true" : undefined',
1308
+ '[attr.aria-setsize]': 'ariaSetSize()',
1309
+ '[attr.aria-posinset]': 'ariaPosInSet()',
1310
+ '[attr.data-highlighted]': 'isHighlighted() ? "" : undefined',
1311
+ '[attr.data-disabled]': 'disabled() ? "" : undefined',
1312
+ '[hidden]': '!isVisible()',
1313
+ '[attr.data-hidden]': 'isVisible() ? undefined : ""',
1314
+ '(pointerdown)': 'onPointerDown($event)',
1315
+ '(mousedown)': 'onMouseDown($event)',
1316
+ '(mouseup)': 'onMouseUp($event)',
1317
+ '(click)': 'onClick()',
1318
+ '(pointermove)': 'onPointerMove()',
1319
+ '(pointerleave)': 'onPointerLeave($event)'
1320
+ }
1321
+ }]
1322
+ }], ctorParameters: () => [], propDecorators: { valueInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], textValueInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "textValue", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], index: [{ type: i0.Input, args: [{ isSignal: true, alias: "index", required: false }] }] } });
1323
+
1324
+ /**
1325
+ * Renders only when its item is selected (e.g. a checkmark). Reuses the combobox item indicator,
1326
+ * which reads the item context provided by {@link RdxAutocompleteItem}.
1327
+ *
1328
+ * @group Components
1329
+ */
1330
+ class RdxAutocompleteItemIndicator {
1331
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteItemIndicator, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1332
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxAutocompleteItemIndicator, isStandalone: true, selector: "[rdxAutocompleteItemIndicator]", exportAs: ["rdxAutocompleteItemIndicator"], hostDirectives: [{ directive: i1.RdxComboboxItemIndicator }], ngImport: i0 }); }
1333
+ }
1334
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteItemIndicator, decorators: [{
1335
+ type: Directive,
1336
+ args: [{
1337
+ selector: '[rdxAutocompleteItemIndicator]',
1338
+ exportAs: 'rdxAutocompleteItemIndicator',
1339
+ hostDirectives: [RdxComboboxItemIndicator]
1340
+ }]
1341
+ }] });
1342
+
1343
+ /**
1344
+ * An accessible label for the autocomplete. Registers its id so the input (and trigger) reference it
1345
+ * via `aria-labelledby`. Reuses the combobox label behavior.
1346
+ *
1347
+ * @group Components
1348
+ */
1349
+ class RdxAutocompleteLabel {
1350
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteLabel, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1351
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxAutocompleteLabel, isStandalone: true, selector: "[rdxAutocompleteLabel]", exportAs: ["rdxAutocompleteLabel"], hostDirectives: [{ directive: i1.RdxComboboxLabel }], ngImport: i0 }); }
1352
+ }
1353
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteLabel, decorators: [{
1354
+ type: Directive,
1355
+ args: [{
1356
+ selector: '[rdxAutocompleteLabel]',
1357
+ exportAs: 'rdxAutocompleteLabel',
1358
+ hostDirectives: [RdxComboboxLabel]
1359
+ }]
1360
+ }] });
1361
+
1362
+ /**
1363
+ * The listbox (or grid) container for suggestions. Carries the id referenced by the input's
1364
+ * `aria-controls`, and switches its role to `grid` when the root has `grid` enabled.
1365
+ *
1366
+ * @group Components
1367
+ */
1368
+ class RdxAutocompleteList {
1369
+ constructor() {
1370
+ this.root = inject(RdxAutocompleteRoot);
1371
+ }
1372
+ onKeydown(event) {
1373
+ if (event.key !== 'Enter') {
1374
+ return;
1375
+ }
1376
+ // Base UI bails early when disabled / read-only — don't swallow Enter (e.g. a form submit).
1377
+ if (this.root.disabledState() || this.root.readOnly()) {
1378
+ return;
1379
+ }
1380
+ const hasHighlight = this.root.virtualized()
1381
+ ? this.root.highlightedIndex() >= 0
1382
+ : this.root.highlightedItem() !== null;
1383
+ if (hasHighlight) {
1384
+ // Base UI `stopEvent`: also stop propagation so a parent keydown handler doesn't re-handle
1385
+ // Enter after the selection.
1386
+ event.preventDefault();
1387
+ event.stopPropagation();
1388
+ this.root.selectHighlighted();
1389
+ }
1390
+ }
1391
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteList, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1392
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxAutocompleteList, isStandalone: true, selector: "[rdxAutocompleteList]", host: { attributes: { "tabindex": "-1" }, listeners: { "keydown": "onKeydown($event)" }, properties: { "attr.role": "root.grid() ? \"grid\" : \"listbox\"", "attr.id": "root.listId" } }, exportAs: ["rdxAutocompleteList"], ngImport: i0 }); }
1393
+ }
1394
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteList, decorators: [{
1395
+ type: Directive,
1396
+ args: [{
1397
+ selector: '[rdxAutocompleteList]',
1398
+ exportAs: 'rdxAutocompleteList',
1399
+ host: {
1400
+ // Base UI: the list is a programmatic focus target (`tabindex="-1"`) and selects the highlighted
1401
+ // item on Enter, for custom layouts that move focus onto the list rather than the input.
1402
+ tabindex: '-1',
1403
+ '[attr.role]': 'root.grid() ? "grid" : "listbox"',
1404
+ '[attr.id]': 'root.listId',
1405
+ '(keydown)': 'onKeydown($event)'
1406
+ }
1407
+ }]
1408
+ }] });
1409
+
1410
+ /**
1411
+ * The popup surface. Composes the popper content (for `data-side` / `data-align`) and a dismissable
1412
+ * layer for outside-dismiss. It does **not** trap focus — focus stays in the input throughout. When
1413
+ * the input lives **inside** the popup (the "input in popup" / emoji-picker pattern), it moves focus
1414
+ * to the input once the popup is positioned.
1415
+ *
1416
+ * @group Components
1417
+ */
1418
+ class RdxAutocompletePopup {
1419
+ constructor() {
1420
+ this.root = inject(RdxAutocompleteRoot);
1421
+ this.floatingContext = inject(RDX_FLOATING_ROOT_CONTEXT);
1422
+ this.registration = inject(RDX_FLOATING_REGISTRATION, { optional: true });
1423
+ this.popper = injectPopperContentWrapperContext();
1424
+ this.element = inject(ElementRef).nativeElement;
1425
+ // Activation policy (ADR 0016 §2 + §3): lock page scroll while a modal popup is OPEN, gated on
1426
+ // `open` (not mounted) so the lock releases at close-start. For a **touch** open the anchored
1427
+ // helper only locks when the popup is effectively viewport-width (a small dropdown stays
1428
+ // swipe-to-dismissable on mobile, §3).
1429
+ useAnchoredScrollLock(computed(() => this.root.open() && this.root.modal()), {
1430
+ touchOpen: () => this.root.openedByTouch(),
1431
+ element: () => this.element
1432
+ });
1433
+ const unregister = this.root.registerTransitionElement(this.element);
1434
+ // Track mounted state so Escape can tell "closing this open popup" from "already closed".
1435
+ this.root.setPopupMounted(true);
1436
+ inject(DestroyRef).onDestroy(() => {
1437
+ unregister();
1438
+ this.root.setPopupMounted(false);
1439
+ });
1440
+ // The popup is this layer's floating element (the inside surface for containment checks).
1441
+ this.floatingContext.setFloatingElement(this.element);
1442
+ // Dismissal (ADR 0015): an outside press, or focus leaving everything, closes the autocomplete. The
1443
+ // input / trigger / clear are registered as "inside" (RdxFloatingInsideElement), so the input keeping
1444
+ // focus — or a press on those parts — never self-dismisses. Escape is owned by the input (it
1445
+ // preventDefaults + closes), so the capability does not handle it (`escapeKey: false`).
1446
+ new RdxDismiss(this.floatingContext, () => this.registration?.node() ?? null, {
1447
+ escapeKey: () => false,
1448
+ outsidePress: () => true,
1449
+ focusOutside: () => true,
1450
+ onDismiss: (reason, event) => this.root.closePopup(true, reason === 'focus-outside' ? 'focus-out' : 'outside-press', event)
1451
+ });
1452
+ // For the "input inside the popup" pattern, move focus to the input once positioned. Use
1453
+ // `afterRenderEffect` (not `effect`): when `isPositioned` flips true the popup's final
1454
+ // position/visibility is applied in the *following* render, so a synchronous `effect` would
1455
+ // call `focus()` while the element is still unfocusable and silently no-op. Running after the
1456
+ // render guarantees the input is focusable.
1457
+ afterRenderEffect(() => {
1458
+ if (!this.popper.isPositioned() || !this.root.open()) {
1459
+ return;
1460
+ }
1461
+ const input = this.root.inputElement();
1462
+ if (input && input.closest('[rdxAutocompletePopup]')) {
1463
+ // Base UI: a touch-open focuses the popup itself so Android keeps the virtual keyboard
1464
+ // closed; mouse/keyboard opens focus (and select) the search input as usual.
1465
+ if (this.root.openedByTouch()) {
1466
+ this.element.focus();
1467
+ }
1468
+ else {
1469
+ input.focus();
1470
+ input.select();
1471
+ }
1472
+ }
1473
+ });
1474
+ }
1475
+ /**
1476
+ * Base UI focus handoff: if focus lands on the popup or the list (the `tabindex="-1"` programmatic
1477
+ * focus targets), hand it back to the input so arrow-key navigation (`aria-activedescendant`) keeps
1478
+ * working. Skipped for a touch interaction, where focus is parked on the popup to keep the Android
1479
+ * virtual keyboard closed.
1480
+ */
1481
+ onFocusIn(event) {
1482
+ if (this.root.openedByTouch()) {
1483
+ return;
1484
+ }
1485
+ const input = this.root.inputElement();
1486
+ const target = event.target;
1487
+ if (!input || !target || target === input) {
1488
+ return;
1489
+ }
1490
+ if (target === this.element || target.matches('[rdxAutocompleteList]')) {
1491
+ input.focus();
1492
+ }
1493
+ }
1494
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompletePopup, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1495
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxAutocompletePopup, isStandalone: true, selector: "[rdxAutocompletePopup]", host: { attributes: { "tabindex": "-1" }, listeners: { "focusin": "onFocusIn($event)" }, properties: { "attr.role": "root.inputLayout() === \"inside\" ? \"dialog\" : \"presentation\"", "attr.data-state": "root.open() ? \"open\" : \"closed\"", "attr.data-open": "root.open() ? \"\" : undefined", "attr.data-closed": "root.open() ? undefined : \"\"", "attr.data-starting-style": "root.transitionStatus() === \"starting\" ? \"\" : undefined", "attr.data-ending-style": "root.transitionStatus() === \"ending\" ? \"\" : undefined" } }, exportAs: ["rdxAutocompletePopup"], hostDirectives: [{ directive: i1$1.RdxPopperContent }, { directive: i2.RdxFloatingNodeRegistration }], ngImport: i0 }); }
1496
+ }
1497
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompletePopup, decorators: [{
1498
+ type: Directive,
1499
+ args: [{
1500
+ selector: '[rdxAutocompletePopup]',
1501
+ exportAs: 'rdxAutocompletePopup',
1502
+ hostDirectives: [RdxPopperContent, RdxFloatingNodeRegistration],
1503
+ host: {
1504
+ // Base UI: a `dialog` (focusable, tabindex -1) when the input lives inside the popup, otherwise
1505
+ // a presentational wrapper around the `listbox` (the List part owns the listbox role).
1506
+ tabindex: '-1',
1507
+ '[attr.role]': 'root.inputLayout() === "inside" ? "dialog" : "presentation"',
1508
+ '[attr.data-state]': 'root.open() ? "open" : "closed"',
1509
+ '[attr.data-open]': 'root.open() ? "" : undefined',
1510
+ '[attr.data-closed]': 'root.open() ? undefined : ""',
1511
+ '[attr.data-starting-style]': 'root.transitionStatus() === "starting" ? "" : undefined',
1512
+ '[attr.data-ending-style]': 'root.transitionStatus() === "ending" ? "" : undefined',
1513
+ '(focusin)': 'onFocusIn($event)'
1514
+ }
1515
+ }]
1516
+ }], ctorParameters: () => [] });
1517
+
1518
+ /**
1519
+ * Structural directive that teleports the autocomplete popup into a container (default
1520
+ * `document.body`) while the autocomplete is open, keeping it mounted until any CSS exit `@keyframes`
1521
+ * finishes. Composes the structural {@link RdxComboboxPortal} (which reads the open state from the
1522
+ * combobox root context provided by `RdxAutocompleteRoot`).
1523
+ *
1524
+ * Apply it with the `*` microsyntax on the positioner —
1525
+ * `<div *rdxAutocompletePortal rdxAutocompletePositioner>` — or as an explicit
1526
+ * `<ng-template rdxAutocompletePortal>`. For a custom container use the explicit form with `[container]`.
1527
+ *
1528
+ * @group Components
1529
+ */
1530
+ class RdxAutocompletePortal {
1531
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompletePortal, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1532
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxAutocompletePortal, isStandalone: true, selector: "ng-template[rdxAutocompletePortal]", exportAs: ["rdxAutocompletePortal"], hostDirectives: [{ directive: i1.RdxComboboxPortal, inputs: ["container", "container"] }], ngImport: i0 }); }
1533
+ }
1534
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompletePortal, decorators: [{
1535
+ type: Directive,
1536
+ args: [{
1537
+ selector: 'ng-template[rdxAutocompletePortal]',
1538
+ exportAs: 'rdxAutocompletePortal',
1539
+ hostDirectives: [{ directive: RdxComboboxPortal, inputs: ['container'] }]
1540
+ }]
1541
+ }] });
1542
+ /**
1543
+ * Dev-mode guard: `rdxAutocompletePortal` is now structural, so the old `<div rdxAutocompletePortal>`
1544
+ * markup would silently stop portaling — fail loudly instead.
1545
+ *
1546
+ * @group Components
1547
+ */
1548
+ class RdxAutocompletePortalMisuseGuard {
1549
+ constructor() {
1550
+ if (isDevMode()) {
1551
+ rdxDevError('autocomplete/portal-on-element', '`rdxAutocompletePortal` is now a structural directive. ' +
1552
+ 'Use `*rdxAutocompletePortal` on the positioner element or `<ng-template rdxAutocompletePortal>`. ' +
1553
+ 'rdxAutocompletePortalPresence has been removed.', 'components/autocomplete');
1554
+ }
1555
+ }
1556
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompletePortalMisuseGuard, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1557
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxAutocompletePortalMisuseGuard, isStandalone: true, selector: "[rdxAutocompletePortal]:not(ng-template)", ngImport: i0 }); }
1558
+ }
1559
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompletePortalMisuseGuard, decorators: [{
1560
+ type: Directive,
1561
+ args: [{
1562
+ selector: '[rdxAutocompletePortal]:not(ng-template)'
1563
+ }]
1564
+ }], ctorParameters: () => [] });
1565
+
1566
+ /**
1567
+ * A visual separator between groups of suggestions (`role="separator"`). Reuses the combobox separator.
1568
+ *
1569
+ * @group Components
1570
+ */
1571
+ class RdxAutocompleteSeparator {
1572
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteSeparator, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1573
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxAutocompleteSeparator, isStandalone: true, selector: "[rdxAutocompleteSeparator]", exportAs: ["rdxAutocompleteSeparator"], hostDirectives: [{ directive: i1.RdxComboboxSeparator }], ngImport: i0 }); }
1574
+ }
1575
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteSeparator, decorators: [{
1576
+ type: Directive,
1577
+ args: [{
1578
+ selector: '[rdxAutocompleteSeparator]',
1579
+ exportAs: 'rdxAutocompleteSeparator',
1580
+ hostDirectives: [RdxComboboxSeparator]
1581
+ }]
1582
+ }] });
1583
+
1584
+ /**
1585
+ * A polite live region for async status (loading, result counts) announced without moving focus.
1586
+ * Reuses the combobox status region.
1587
+ *
1588
+ * @group Components
1589
+ */
1590
+ class RdxAutocompleteStatus {
1591
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteStatus, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1592
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxAutocompleteStatus, isStandalone: true, selector: "[rdxAutocompleteStatus]", exportAs: ["rdxAutocompleteStatus"], hostDirectives: [{ directive: i1.RdxComboboxStatus }], ngImport: i0 }); }
1593
+ }
1594
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteStatus, decorators: [{
1595
+ type: Directive,
1596
+ args: [{
1597
+ selector: '[rdxAutocompleteStatus]',
1598
+ exportAs: 'rdxAutocompleteStatus',
1599
+ hostDirectives: [RdxComboboxStatus]
1600
+ }]
1601
+ }] });
1602
+
1603
+ /**
1604
+ * Toggles the autocomplete popup. Reuses the combobox trigger: a `tabindex="-1"` toggle when the input
1605
+ * sits outside the popup, or the focusable `role="combobox"` control when the input is inside it.
1606
+ *
1607
+ * @group Components
1608
+ */
1609
+ class RdxAutocompleteTrigger {
1610
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1611
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxAutocompleteTrigger, isStandalone: true, selector: "button[rdxAutocompleteTrigger]", exportAs: ["rdxAutocompleteTrigger"], hostDirectives: [{ directive: i1.RdxComboboxTrigger }], ngImport: i0 }); }
1612
+ }
1613
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteTrigger, decorators: [{
1614
+ type: Directive,
1615
+ args: [{
1616
+ selector: 'button[rdxAutocompleteTrigger]',
1617
+ exportAs: 'rdxAutocompleteTrigger',
1618
+ hostDirectives: [RdxComboboxTrigger]
1619
+ }]
1620
+ }] });
1621
+
1622
+ /**
1623
+ * Renders the current input value as text. Useful for a read-only display of the committed value.
1624
+ * Read `slotText()` in the template. Exposes `data-placeholder` while the value is empty.
1625
+ *
1626
+ * @example
1627
+ * <span #value="rdxAutocompleteValue" rdxAutocompleteValue placeholder="Empty">{{ value.slotText() }}</span>
1628
+ *
1629
+ * @group Components
1630
+ */
1631
+ class RdxAutocompleteValue {
1632
+ constructor() {
1633
+ this.root = inject(RdxAutocompleteRoot);
1634
+ /** Text shown when the value is empty. */
1635
+ this.placeholder = input(...(ngDevMode ? [undefined, { debugName: "placeholder" }] : /* istanbul ignore next */ []));
1636
+ this.isEmpty = computed(() => !this.root.value(), ...(ngDevMode ? [{ debugName: "isEmpty" }] : /* istanbul ignore next */ []));
1637
+ /** The current input value, or the `placeholder` when empty. */
1638
+ this.slotText = computed(() => this.root.value() || (this.placeholder() ?? ''), ...(ngDevMode ? [{ debugName: "slotText" }] : /* istanbul ignore next */ []));
1639
+ }
1640
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteValue, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1641
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxAutocompleteValue, isStandalone: true, selector: "[rdxAutocompleteValue]", inputs: { placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-placeholder": "isEmpty() ? \"\" : undefined" } }, exportAs: ["rdxAutocompleteValue"], ngImport: i0 }); }
1642
+ }
1643
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteValue, decorators: [{
1644
+ type: Directive,
1645
+ args: [{
1646
+ selector: '[rdxAutocompleteValue]',
1647
+ exportAs: 'rdxAutocompleteValue',
1648
+ host: {
1649
+ '[attr.data-placeholder]': 'isEmpty() ? "" : undefined'
1650
+ }
1651
+ }]
1652
+ }], propDecorators: { placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }] } });
1653
+
1654
+ const _importsAutocomplete = [
1655
+ RdxAutocompleteRoot,
1656
+ RdxAutocompleteAnchor,
1657
+ RdxAutocompleteLabel,
1658
+ RdxAutocompleteInputGroup,
1659
+ RdxAutocompleteInput,
1660
+ RdxAutocompleteValue,
1661
+ RdxAutocompleteTrigger,
1662
+ RdxAutocompleteIcon,
1663
+ RdxAutocompleteClear,
1664
+ RdxAutocompletePortal,
1665
+ RdxAutocompletePortalMisuseGuard,
1666
+ RdxAutocompleteBackdrop,
1667
+ RdxAutocompletePositioner,
1668
+ RdxAutocompletePopup,
1669
+ RdxAutocompleteArrow,
1670
+ RdxAutocompleteList,
1671
+ RdxAutocompleteRow,
1672
+ RdxAutocompleteSeparator,
1673
+ RdxAutocompleteItem,
1674
+ RdxAutocompleteItemIndicator,
1675
+ RdxAutocompleteGroup,
1676
+ RdxAutocompleteGroupLabel,
1677
+ RdxAutocompleteEmpty,
1678
+ RdxAutocompleteStatus
1679
+ ];
1680
+ class RdxAutocompleteModule {
1681
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1682
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteModule, imports: [RdxAutocompleteRoot,
1683
+ RdxAutocompleteAnchor,
1684
+ RdxAutocompleteLabel,
1685
+ RdxAutocompleteInputGroup,
1686
+ RdxAutocompleteInput,
1687
+ RdxAutocompleteValue,
1688
+ RdxAutocompleteTrigger,
1689
+ RdxAutocompleteIcon,
1690
+ RdxAutocompleteClear,
1691
+ RdxAutocompletePortal,
1692
+ RdxAutocompletePortalMisuseGuard,
1693
+ RdxAutocompleteBackdrop,
1694
+ RdxAutocompletePositioner,
1695
+ RdxAutocompletePopup,
1696
+ RdxAutocompleteArrow,
1697
+ RdxAutocompleteList,
1698
+ RdxAutocompleteRow,
1699
+ RdxAutocompleteSeparator,
1700
+ RdxAutocompleteItem,
1701
+ RdxAutocompleteItemIndicator,
1702
+ RdxAutocompleteGroup,
1703
+ RdxAutocompleteGroupLabel,
1704
+ RdxAutocompleteEmpty,
1705
+ RdxAutocompleteStatus], exports: [RdxAutocompleteRoot,
1706
+ RdxAutocompleteAnchor,
1707
+ RdxAutocompleteLabel,
1708
+ RdxAutocompleteInputGroup,
1709
+ RdxAutocompleteInput,
1710
+ RdxAutocompleteValue,
1711
+ RdxAutocompleteTrigger,
1712
+ RdxAutocompleteIcon,
1713
+ RdxAutocompleteClear,
1714
+ RdxAutocompletePortal,
1715
+ RdxAutocompletePortalMisuseGuard,
1716
+ RdxAutocompleteBackdrop,
1717
+ RdxAutocompletePositioner,
1718
+ RdxAutocompletePopup,
1719
+ RdxAutocompleteArrow,
1720
+ RdxAutocompleteList,
1721
+ RdxAutocompleteRow,
1722
+ RdxAutocompleteSeparator,
1723
+ RdxAutocompleteItem,
1724
+ RdxAutocompleteItemIndicator,
1725
+ RdxAutocompleteGroup,
1726
+ RdxAutocompleteGroupLabel,
1727
+ RdxAutocompleteEmpty,
1728
+ RdxAutocompleteStatus] }); }
1729
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteModule }); }
1730
+ }
1731
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxAutocompleteModule, decorators: [{
1732
+ type: NgModule,
1733
+ args: [{
1734
+ imports: [..._importsAutocomplete],
1735
+ exports: [..._importsAutocomplete]
1736
+ }]
1737
+ }] });
1738
+
1739
+ /**
1740
+ * Generated bundle index. Do not edit.
1741
+ */
1742
+
1743
+ export { RdxAutocompleteAnchor, RdxAutocompleteArrow, RdxAutocompleteBackdrop, RdxAutocompleteClear, RdxAutocompleteEmpty, RdxAutocompleteGroup, RdxAutocompleteGroupLabel, RdxAutocompleteIcon, RdxAutocompleteInput, RdxAutocompleteInputGroup, RdxAutocompleteItem, RdxAutocompleteItemIndicator, RdxAutocompleteLabel, RdxAutocompleteList, RdxAutocompleteModule, RdxAutocompletePopup, RdxAutocompletePortal, RdxAutocompletePortalMisuseGuard, RdxAutocompletePositioner, RdxAutocompleteRoot, RdxAutocompleteRow, RdxAutocompleteSeparator, RdxAutocompleteStatus, RdxAutocompleteTrigger, RdxAutocompleteValue, _importsAutocomplete };
1744
+ //# sourceMappingURL=radix-ng-primitives-autocomplete.mjs.map