@radix-ng/primitives 1.0.5 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/aspect-ratio/README.md +1 -1
- package/fesm2022/radix-ng-primitives-accordion.mjs +40 -27
- package/fesm2022/radix-ng-primitives-accordion.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-alert-dialog.mjs +34 -34
- package/fesm2022/radix-ng-primitives-arrow.mjs +3 -3
- package/fesm2022/radix-ng-primitives-aspect-ratio.mjs +11 -35
- package/fesm2022/radix-ng-primitives-aspect-ratio.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-autocomplete.mjs +175 -125
- package/fesm2022/radix-ng-primitives-autocomplete.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-avatar.mjs +92 -35
- package/fesm2022/radix-ng-primitives-avatar.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-button.mjs +11 -7
- package/fesm2022/radix-ng-primitives-button.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-calendar.mjs +140 -90
- package/fesm2022/radix-ng-primitives-calendar.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-checkbox.mjs +63 -46
- package/fesm2022/radix-ng-primitives-checkbox.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-collapsible.mjs +37 -25
- package/fesm2022/radix-ng-primitives-collapsible.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-combobox.mjs +278 -177
- package/fesm2022/radix-ng-primitives-combobox.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-composite.mjs +50 -33
- package/fesm2022/radix-ng-primitives-composite.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-config.mjs +7 -5
- package/fesm2022/radix-ng-primitives-config.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-context-menu.mjs +48 -22
- package/fesm2022/radix-ng-primitives-context-menu.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-core.mjs +44 -28
- package/fesm2022/radix-ng-primitives-core.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-cropper.mjs +73 -45
- package/fesm2022/radix-ng-primitives-cropper.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-date-field.mjs +70 -40
- package/fesm2022/radix-ng-primitives-date-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-dialog.mjs +93 -67
- package/fesm2022/radix-ng-primitives-dialog.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-direction-provider.mjs +5 -4
- package/fesm2022/radix-ng-primitives-direction-provider.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-dismissable-layer.mjs +20 -16
- package/fesm2022/radix-ng-primitives-dismissable-layer.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-drawer.mjs +107 -81
- package/fesm2022/radix-ng-primitives-drawer.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-editable.mjs +53 -39
- package/fesm2022/radix-ng-primitives-editable.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-field.mjs +76 -50
- package/fesm2022/radix-ng-primitives-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-fieldset.mjs +8 -7
- package/fesm2022/radix-ng-primitives-fieldset.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-floating-focus-manager.mjs +77 -40
- package/fesm2022/radix-ng-primitives-floating-focus-manager.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-focus-guards.mjs +3 -3
- package/fesm2022/radix-ng-primitives-focus-scope.mjs +7 -5
- package/fesm2022/radix-ng-primitives-focus-scope.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-form.mjs +26 -17
- package/fesm2022/radix-ng-primitives-form.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-input.mjs +41 -22
- package/fesm2022/radix-ng-primitives-input.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-label.mjs +11 -8
- package/fesm2022/radix-ng-primitives-label.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-menu.mjs +274 -154
- package/fesm2022/radix-ng-primitives-menu.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-menubar.mjs +35 -17
- package/fesm2022/radix-ng-primitives-menubar.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-meter.mjs +41 -30
- package/fesm2022/radix-ng-primitives-meter.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-navigation-menu.mjs +220 -183
- package/fesm2022/radix-ng-primitives-navigation-menu.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-number-field.mjs +93 -61
- package/fesm2022/radix-ng-primitives-number-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-pagination.mjs +48 -38
- package/fesm2022/radix-ng-primitives-pagination.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-popover.mjs +150 -107
- package/fesm2022/radix-ng-primitives-popover.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-popper.mjs +79 -47
- package/fesm2022/radix-ng-primitives-popper.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-portal.mjs +20 -13
- package/fesm2022/radix-ng-primitives-portal.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-presence.mjs +3 -3
- package/fesm2022/radix-ng-primitives-preview-card.mjs +119 -74
- package/fesm2022/radix-ng-primitives-preview-card.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-progress.mjs +73 -46
- package/fesm2022/radix-ng-primitives-progress.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-radio.mjs +58 -40
- package/fesm2022/radix-ng-primitives-radio.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-scroll-area.mjs +57 -41
- package/fesm2022/radix-ng-primitives-scroll-area.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-select.mjs +595 -102
- package/fesm2022/radix-ng-primitives-select.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-separator.mjs +11 -15
- package/fesm2022/radix-ng-primitives-separator.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-slider.mjs +101 -64
- package/fesm2022/radix-ng-primitives-slider.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-stepper.mjs +53 -39
- package/fesm2022/radix-ng-primitives-stepper.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-switch.mjs +25 -20
- package/fesm2022/radix-ng-primitives-switch.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-tabs.mjs +76 -51
- package/fesm2022/radix-ng-primitives-tabs.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-time-field.mjs +72 -41
- package/fesm2022/radix-ng-primitives-time-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toast.mjs +75 -56
- package/fesm2022/radix-ng-primitives-toast.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toggle-group.mjs +39 -23
- package/fesm2022/radix-ng-primitives-toggle-group.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toggle.mjs +36 -36
- package/fesm2022/radix-ng-primitives-toggle.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toolbar.mjs +52 -31
- package/fesm2022/radix-ng-primitives-toolbar.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-tooltip.mjs +118 -63
- package/fesm2022/radix-ng-primitives-tooltip.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-visually-hidden.mjs +31 -20
- package/fesm2022/radix-ng-primitives-visually-hidden.mjs.map +1 -1
- package/package.json +2 -2
- package/types/radix-ng-primitives-accordion.d.ts +1 -0
- package/types/radix-ng-primitives-aspect-ratio.d.ts +10 -23
- package/types/radix-ng-primitives-autocomplete.d.ts +3 -1
- package/types/radix-ng-primitives-avatar.d.ts +51 -25
- package/types/radix-ng-primitives-checkbox.d.ts +26 -98
- package/types/radix-ng-primitives-combobox.d.ts +28 -9
- package/types/radix-ng-primitives-context-menu.d.ts +2 -0
- package/types/radix-ng-primitives-dialog.d.ts +6 -3
- package/types/radix-ng-primitives-field.d.ts +33 -207
- package/types/radix-ng-primitives-floating-focus-manager.d.ts +11 -0
- package/types/radix-ng-primitives-form.d.ts +24 -33
- package/types/radix-ng-primitives-label.d.ts +3 -2
- package/types/radix-ng-primitives-menu.d.ts +47 -15
- package/types/radix-ng-primitives-menubar.d.ts +6 -1
- package/types/radix-ng-primitives-navigation-menu.d.ts +8 -6
- package/types/radix-ng-primitives-number-field.d.ts +1 -1
- package/types/radix-ng-primitives-popover.d.ts +12 -4
- package/types/radix-ng-primitives-preview-card.d.ts +18 -5
- package/types/radix-ng-primitives-progress.d.ts +59 -121
- package/types/radix-ng-primitives-radio.d.ts +0 -1
- package/types/radix-ng-primitives-select.d.ts +186 -391
- package/types/radix-ng-primitives-separator.d.ts +0 -7
- package/types/radix-ng-primitives-toggle-group.d.ts +7 -3
- package/types/radix-ng-primitives-toggle.d.ts +8 -8
- package/types/radix-ng-primitives-toolbar.d.ts +2 -0
- package/types/radix-ng-primitives-tooltip.d.ts +17 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, model, signal, computed, ElementRef, input, booleanAttribute, output,
|
|
2
|
+
import { inject, model, signal, computed, ElementRef, input, booleanAttribute, output, effect, untracked, Directive, InjectionToken, Injector, DestroyRef, afterNextRender, linkedSignal, contentChild, forwardRef, isDevMode } from '@angular/core';
|
|
3
3
|
import * as i3 from '@radix-ng/primitives/core';
|
|
4
|
-
import { isEqual, getActiveElement, createContext, injectId, createFloatingRootContext, useTransitionStatus, isNullish, createCancelableChangeEventDetails, provideFloatingTree, provideFloatingRootContext, RDX_FLOATING_ROOT_CONTEXT, RDX_FLOATING_REGISTRATION, useListHighlight, useAnchoredScrollLock, RdxFloatingNodeRegistration, handleAndDispatchCustomEvent, rdxDevError, setupInternalBackdrop } from '@radix-ng/primitives/core';
|
|
4
|
+
import { isEqual, getActiveElement, createContext, injectId, createFloatingRootContext, useTransitionStatus, isNullish, createCancelableChangeEventDetails, provideFloatingTree, provideFloatingRootContext, RDX_FLOATING_ROOT_CONTEXT, RDX_FLOATING_REGISTRATION, useListHighlight, useAnchoredScrollLock, RdxFloatingNodeRegistration, handleAndDispatchCustomEvent, resizeEffect, clamp, rdxDevError, setupInternalBackdrop } from '@radix-ng/primitives/core';
|
|
5
5
|
import { injectDirection } from '@radix-ng/primitives/direction-provider';
|
|
6
6
|
import * as i2 from '@radix-ng/primitives/floating-focus-manager';
|
|
7
7
|
import { getInteractionTypeFromEvent, provideFloatingFocusManagerConfig, RdxFloatingFocusManager, createRdxTriggerInteraction } from '@radix-ng/primitives/floating-focus-manager';
|
|
@@ -70,6 +70,8 @@ const context$2 = () => {
|
|
|
70
70
|
openInteractionType: context.openInteractionType,
|
|
71
71
|
closeInteractionType: context.closeInteractionType,
|
|
72
72
|
disabled: context.disabled,
|
|
73
|
+
readOnly: context.readOnly,
|
|
74
|
+
required: context.required,
|
|
73
75
|
modal: context.modal,
|
|
74
76
|
isEmptyModelValue: context.isEmptyModelValue,
|
|
75
77
|
transitionStatus: context.transitionStatus,
|
|
@@ -102,31 +104,48 @@ const [injectSelectRootContext, provideSelectRootContext] = createContext('RdxSe
|
|
|
102
104
|
class RdxSelectRoot {
|
|
103
105
|
constructor() {
|
|
104
106
|
this.contentId = injectId('rdx-select-content-');
|
|
105
|
-
this.open = model(false,
|
|
107
|
+
this.open = model(false, /* @ts-ignore */
|
|
108
|
+
...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
|
|
106
109
|
/** Whether the current open was initiated by **touch** (ADR 0016 §3 — gates the anchored scroll lock). */
|
|
107
|
-
this.openedByTouch = signal(false,
|
|
110
|
+
this.openedByTouch = signal(false, /* @ts-ignore */
|
|
111
|
+
...(ngDevMode ? [{ debugName: "openedByTouch" }] : /* istanbul ignore next */ []));
|
|
108
112
|
/** How the select was opened. Base UI names this state `openMethod`. */
|
|
109
|
-
this.openInteractionType = signal(null,
|
|
113
|
+
this.openInteractionType = signal(null, /* @ts-ignore */
|
|
114
|
+
...(ngDevMode ? [{ debugName: "openInteractionType" }] : /* istanbul ignore next */ []));
|
|
110
115
|
/** How the select was closed. */
|
|
111
|
-
this.closeInteractionType = signal(null,
|
|
116
|
+
this.closeInteractionType = signal(null, /* @ts-ignore */
|
|
117
|
+
...(ngDevMode ? [{ debugName: "closeInteractionType" }] : /* istanbul ignore next */ []));
|
|
112
118
|
/** Public Base UI-aligned alias for the open interaction type. */
|
|
113
|
-
this.openMethod = computed(() => this.openInteractionType(),
|
|
119
|
+
this.openMethod = computed(() => this.openInteractionType(), /* @ts-ignore */
|
|
120
|
+
...(ngDevMode ? [{ debugName: "openMethod" }] : /* istanbul ignore next */ []));
|
|
114
121
|
/** Per-popup floating root context (ADR 0015) — `open` / `triggers` / reference for the dismissal engine. */
|
|
115
122
|
this.floatingContext = createFloatingRootContext({
|
|
116
123
|
ownerDocument: inject(ElementRef).nativeElement.ownerDocument,
|
|
117
124
|
open: () => this.open()
|
|
118
125
|
});
|
|
119
|
-
this.value = model(
|
|
126
|
+
this.value = model(/* @ts-ignore */
|
|
127
|
+
...(ngDevMode ? [undefined, { debugName: "value" }] : /* istanbul ignore next */ []));
|
|
128
|
+
/** Initial value for the uncontrolled case. Applied once on init; `value`/`[(value)]` take over after. */
|
|
129
|
+
this.defaultValue = input(/* @ts-ignore */
|
|
130
|
+
...(ngDevMode ? [undefined, { debugName: "defaultValue" }] : /* istanbul ignore next */ []));
|
|
131
|
+
/** Whether the select is initially open (uncontrolled). Applied once on init. */
|
|
132
|
+
this.defaultOpen = input(false, { ...(ngDevMode ? { debugName: "defaultOpen" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
120
133
|
this.multiple = input(false, { ...(ngDevMode ? { debugName: "multiple" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
121
134
|
this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
135
|
+
/** When `true`, the value cannot be changed by the user (the popup can still be opened to view it). */
|
|
136
|
+
this.readOnly = input(false, { ...(ngDevMode ? { debugName: "readOnly" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
137
|
+
/** Marks the control as required — reflected on the trigger as `aria-required` / `data-required`. */
|
|
138
|
+
this.required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
122
139
|
/** Whether the popup is modal: locks page scroll and makes outside content inert while open. */
|
|
123
140
|
this.modal = input(true, { ...(ngDevMode ? { debugName: "modal" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
124
141
|
this.dirInput = input(undefined, { ...(ngDevMode ? { debugName: "dirInput" } : /* istanbul ignore next */ {}), alias: 'dir' });
|
|
125
142
|
this.dir = injectDirection(this.dirInput);
|
|
126
143
|
/** How item values are compared for equality — a function `(a, b) => boolean` or an object key. */
|
|
127
|
-
this.isItemEqualToValue = input(
|
|
144
|
+
this.isItemEqualToValue = input(/* @ts-ignore */
|
|
145
|
+
...(ngDevMode ? [undefined, { debugName: "isItemEqualToValue" }] : /* istanbul ignore next */ []));
|
|
128
146
|
/** Converts a value to its display label (used by `RdxSelectValue`). */
|
|
129
|
-
this.itemToStringLabel = input(
|
|
147
|
+
this.itemToStringLabel = input(/* @ts-ignore */
|
|
148
|
+
...(ngDevMode ? [undefined, { debugName: "itemToStringLabel" }] : /* istanbul ignore next */ []));
|
|
130
149
|
/** Emits before an open-state change is committed; call `eventDetails.cancel()` to veto it. */
|
|
131
150
|
this.onOpenChange = output();
|
|
132
151
|
/** Emits before a value change is committed; call `eventDetails.cancel()` to veto it. */
|
|
@@ -144,8 +163,12 @@ class RdxSelectRoot {
|
|
|
144
163
|
return value.length === 0;
|
|
145
164
|
}
|
|
146
165
|
return isNullish(value);
|
|
147
|
-
},
|
|
148
|
-
|
|
166
|
+
}, /* @ts-ignore */
|
|
167
|
+
...(ngDevMode ? [{ debugName: "isEmptyModelValue" }] : /* istanbul ignore next */ []));
|
|
168
|
+
this.hasAppliedDefaultValue = false;
|
|
169
|
+
this.hasAppliedDefaultOpen = false;
|
|
170
|
+
this.optionsSet = signal(new Set(), /* @ts-ignore */
|
|
171
|
+
...(ngDevMode ? [{ debugName: "optionsSet" }] : /* istanbul ignore next */ []));
|
|
149
172
|
// The native `select` only associates the correct default value if the corresponding
|
|
150
173
|
// `option` is rendered as a child **at the same time** as itself.
|
|
151
174
|
// Because it might take a few renders for our items to gather the information to build
|
|
@@ -155,13 +178,33 @@ class RdxSelectRoot {
|
|
|
155
178
|
return Array.from(this.optionsSet())
|
|
156
179
|
.map((option) => option.value)
|
|
157
180
|
.join(';');
|
|
158
|
-
},
|
|
159
|
-
|
|
160
|
-
this.
|
|
181
|
+
}, /* @ts-ignore */
|
|
182
|
+
...(ngDevMode ? [{ debugName: "nativeSelectKey" }] : /* istanbul ignore next */ []));
|
|
183
|
+
this.triggerElement = signal(null, /* @ts-ignore */
|
|
184
|
+
...(ngDevMode ? [{ debugName: "triggerElement" }] : /* istanbul ignore next */ []));
|
|
185
|
+
this.valueElement = signal(null, /* @ts-ignore */
|
|
186
|
+
...(ngDevMode ? [{ debugName: "valueElement" }] : /* istanbul ignore next */ []));
|
|
161
187
|
this.triggerPointerDownPosRef = signal({
|
|
162
188
|
x: 0,
|
|
163
189
|
y: 0
|
|
164
|
-
},
|
|
190
|
+
}, /* @ts-ignore */
|
|
191
|
+
...(ngDevMode ? [{ debugName: "triggerPointerDownPosRef" }] : /* istanbul ignore next */ []));
|
|
192
|
+
// Seed the uncontrolled value/open exactly once, then hand off to the model (so a later user
|
|
193
|
+
// change is not snapped back by the still-set default input).
|
|
194
|
+
effect(() => {
|
|
195
|
+
const defaultValue = this.defaultValue();
|
|
196
|
+
if (!this.hasAppliedDefaultValue && defaultValue !== undefined) {
|
|
197
|
+
this.hasAppliedDefaultValue = true;
|
|
198
|
+
this.value.set(defaultValue);
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
effect(() => {
|
|
202
|
+
const defaultOpen = this.defaultOpen();
|
|
203
|
+
if (!this.hasAppliedDefaultOpen && defaultOpen) {
|
|
204
|
+
this.hasAppliedDefaultOpen = true;
|
|
205
|
+
this.open.set(defaultOpen);
|
|
206
|
+
}
|
|
207
|
+
});
|
|
165
208
|
let previousOpen = untracked(this.open);
|
|
166
209
|
effect(() => {
|
|
167
210
|
const open = this.open();
|
|
@@ -192,10 +235,16 @@ class RdxSelectRoot {
|
|
|
192
235
|
return Array.from(this.optionsSet()).find((option) => valueComparator(value, option.value, this.isItemEqualToValue()));
|
|
193
236
|
}
|
|
194
237
|
setValue(value, reason = 'none', event = new Event('select.value-change')) {
|
|
238
|
+
if (this.readOnly()) {
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
195
241
|
const nextValue = this.multiple()
|
|
196
242
|
? (() => {
|
|
197
243
|
const current = this.value();
|
|
198
244
|
const array = Array.isArray(current) ? [...current] : [];
|
|
245
|
+
if (value === undefined) {
|
|
246
|
+
return array;
|
|
247
|
+
}
|
|
199
248
|
const index = array.findIndex((i) => compare(i, value, this.isItemEqualToValue()));
|
|
200
249
|
index === -1 ? array.push(value) : array.splice(index, 1);
|
|
201
250
|
return [...array];
|
|
@@ -206,12 +255,7 @@ class RdxSelectRoot {
|
|
|
206
255
|
if (eventDetails.isCanceled()) {
|
|
207
256
|
return false;
|
|
208
257
|
}
|
|
209
|
-
|
|
210
|
-
this.value.set(nextValue);
|
|
211
|
-
}
|
|
212
|
-
else {
|
|
213
|
-
this.value.set(nextValue);
|
|
214
|
-
}
|
|
258
|
+
this.value.set(nextValue);
|
|
215
259
|
return true;
|
|
216
260
|
}
|
|
217
261
|
setOpen(open, reason = 'none', event) {
|
|
@@ -232,15 +276,15 @@ class RdxSelectRoot {
|
|
|
232
276
|
}
|
|
233
277
|
return true;
|
|
234
278
|
}
|
|
235
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
236
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "
|
|
279
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectRoot, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
280
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: RdxSelectRoot, isStandalone: true, selector: "[rdxSelectRoot]", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, defaultValue: { classPropertyName: "defaultValue", publicName: "defaultValue", isSignal: true, isRequired: false, transformFunction: null }, defaultOpen: { classPropertyName: "defaultOpen", publicName: "defaultOpen", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", 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 }, modal: { classPropertyName: "modal", publicName: "modal", isSignal: true, isRequired: false, transformFunction: null }, dirInput: { classPropertyName: "dirInput", publicName: "dir", isSignal: true, isRequired: false, transformFunction: null }, isItemEqualToValue: { classPropertyName: "isItemEqualToValue", publicName: "isItemEqualToValue", isSignal: true, isRequired: false, transformFunction: null }, itemToStringLabel: { classPropertyName: "itemToStringLabel", publicName: "itemToStringLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange", value: "valueChange", onOpenChange: "onOpenChange", onValueChange: "onValueChange", onOpenChangeComplete: "onOpenChangeComplete" }, providers: [
|
|
237
281
|
provideSelectRootContext(context$2),
|
|
238
282
|
// New floating foundation (ADR 0015/0017) — the dismissal capability reads this shared context.
|
|
239
283
|
provideFloatingTree(),
|
|
240
284
|
provideFloatingRootContext(() => inject(RdxSelectRoot).floatingContext)
|
|
241
285
|
], exportAs: ["rdxSelectRoot"], hostDirectives: [{ directive: i1.RdxPopper }], ngImport: i0 }); }
|
|
242
286
|
}
|
|
243
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
287
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectRoot, decorators: [{
|
|
244
288
|
type: Directive,
|
|
245
289
|
args: [{
|
|
246
290
|
selector: '[rdxSelectRoot]',
|
|
@@ -253,7 +297,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
253
297
|
],
|
|
254
298
|
hostDirectives: [RdxPopper]
|
|
255
299
|
}]
|
|
256
|
-
}], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], modal: [{ type: i0.Input, args: [{ isSignal: true, alias: "modal", required: false }] }], dirInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "dir", required: false }] }], isItemEqualToValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "isItemEqualToValue", required: false }] }], itemToStringLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemToStringLabel", required: false }] }], onOpenChange: [{ type: i0.Output, args: ["onOpenChange"] }], onValueChange: [{ type: i0.Output, args: ["onValueChange"] }], onOpenChangeComplete: [{ type: i0.Output, args: ["onOpenChangeComplete"] }] } });
|
|
300
|
+
}], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], 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 }] }], defaultOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultOpen", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", 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 }] }], modal: [{ type: i0.Input, args: [{ isSignal: true, alias: "modal", required: false }] }], dirInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "dir", required: false }] }], isItemEqualToValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "isItemEqualToValue", required: false }] }], itemToStringLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemToStringLabel", required: false }] }], onOpenChange: [{ type: i0.Output, args: ["onOpenChange"] }], onValueChange: [{ type: i0.Output, args: ["onValueChange"] }], onOpenChangeComplete: [{ type: i0.Output, args: ["onOpenChangeComplete"] }] } });
|
|
257
301
|
|
|
258
302
|
/**
|
|
259
303
|
* An overlay rendered beneath the popup in `modal` mode. Place it inside the portal/presence; style
|
|
@@ -265,19 +309,20 @@ class RdxSelectBackdrop {
|
|
|
265
309
|
constructor() {
|
|
266
310
|
this.rootContext = injectSelectRootContext();
|
|
267
311
|
}
|
|
268
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
269
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
312
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectBackdrop, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
313
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: RdxSelectBackdrop, isStandalone: true, selector: "[rdxSelectBackdrop]", host: { attributes: { "aria-hidden": "true" }, properties: { "attr.data-open": "rootContext.open() ? \"\" : undefined", "attr.data-closed": "rootContext.open() ? undefined : \"\"", "attr.data-starting-style": "rootContext.transitionStatus() === \"starting\" ? \"\" : undefined", "attr.data-ending-style": "rootContext.transitionStatus() === \"ending\" ? \"\" : undefined" } }, exportAs: ["rdxSelectBackdrop"], ngImport: i0 }); }
|
|
270
314
|
}
|
|
271
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
315
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectBackdrop, decorators: [{
|
|
272
316
|
type: Directive,
|
|
273
317
|
args: [{
|
|
274
318
|
selector: '[rdxSelectBackdrop]',
|
|
275
319
|
exportAs: 'rdxSelectBackdrop',
|
|
276
320
|
host: {
|
|
277
321
|
'aria-hidden': 'true',
|
|
278
|
-
'[attr.data-state]': 'rootContext.open() ? "open" : "closed"',
|
|
279
322
|
'[attr.data-open]': 'rootContext.open() ? "" : undefined',
|
|
280
|
-
'[attr.data-closed]': 'rootContext.open() ? undefined : ""'
|
|
323
|
+
'[attr.data-closed]': 'rootContext.open() ? undefined : ""',
|
|
324
|
+
'[attr.data-starting-style]': 'rootContext.transitionStatus() === "starting" ? "" : undefined',
|
|
325
|
+
'[attr.data-ending-style]': 'rootContext.transitionStatus() === "ending" ? "" : undefined'
|
|
281
326
|
}
|
|
282
327
|
}]
|
|
283
328
|
}] });
|
|
@@ -286,10 +331,10 @@ class RdxSelectGroup {
|
|
|
286
331
|
constructor() {
|
|
287
332
|
this.id = injectId('rdx-select-group-');
|
|
288
333
|
}
|
|
289
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
290
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
334
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectGroup, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
335
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: RdxSelectGroup, isStandalone: true, selector: "[rdxSelectGroup]", host: { attributes: { "role": "group" }, properties: { "attr.aria-labelledby": "id" } }, exportAs: ["rdxSelectGroup"], ngImport: i0 }); }
|
|
291
336
|
}
|
|
292
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
337
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectGroup, decorators: [{
|
|
293
338
|
type: Directive,
|
|
294
339
|
args: [{
|
|
295
340
|
selector: '[rdxSelectGroup]',
|
|
@@ -302,10 +347,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
302
347
|
}] });
|
|
303
348
|
|
|
304
349
|
class RdxSelectGroupLabel {
|
|
305
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
306
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
350
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectGroupLabel, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
351
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: RdxSelectGroupLabel, isStandalone: true, selector: "[rdxSelectGroupLabel]", ngImport: i0 }); }
|
|
307
352
|
}
|
|
308
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
353
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectGroupLabel, decorators: [{
|
|
309
354
|
type: Directive,
|
|
310
355
|
args: [{
|
|
311
356
|
selector: '[rdxSelectGroupLabel]',
|
|
@@ -319,10 +364,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
319
364
|
* @group Components
|
|
320
365
|
*/
|
|
321
366
|
class RdxSelectIcon {
|
|
322
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
323
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
367
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectIcon, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
368
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: RdxSelectIcon, isStandalone: true, selector: "[rdxSelectIcon]", host: { attributes: { "aria-hidden": "true" } }, exportAs: ["rdxSelectIcon"], ngImport: i0 }); }
|
|
324
369
|
}
|
|
325
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
370
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectIcon, decorators: [{
|
|
326
371
|
type: Directive,
|
|
327
372
|
args: [{
|
|
328
373
|
selector: '[rdxSelectIcon]',
|
|
@@ -333,6 +378,42 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
333
378
|
}]
|
|
334
379
|
}] });
|
|
335
380
|
|
|
381
|
+
/**
|
|
382
|
+
* Wraps an array around itself at a given start index
|
|
383
|
+
* Example: `wrapArray(['a', 'b', 'c', 'd'], 2) === ['c', 'd', 'a', 'b']`
|
|
384
|
+
*/
|
|
385
|
+
function wrapArray(array, startIndex) {
|
|
386
|
+
return array.map((_, index) => array[(startIndex + index) % array.length]);
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* This is the "meat" of the typeahead matching logic. It takes in all the values,
|
|
390
|
+
* the search and the current match, and returns the next match (or `undefined`).
|
|
391
|
+
*
|
|
392
|
+
* We normalize the search because if a user has repeatedly pressed a character,
|
|
393
|
+
* we want the exact same behavior as if we only had that one character
|
|
394
|
+
* (ie. cycle through options starting with that character)
|
|
395
|
+
*
|
|
396
|
+
* We also reorder the values by wrapping the array around the current match.
|
|
397
|
+
* This is so we always look forward from the current match, and picking the first
|
|
398
|
+
* match will always be the correct one.
|
|
399
|
+
*
|
|
400
|
+
* Finally, if the normalized search is exactly one character, we exclude the
|
|
401
|
+
* current match from the values because otherwise it would be the first to match always
|
|
402
|
+
* and focus would never move. This is as opposed to the regular case, where we
|
|
403
|
+
* don't want focus to move if the current match still matches.
|
|
404
|
+
*/
|
|
405
|
+
function getNextMatch(values, search, currentMatch) {
|
|
406
|
+
const isRepeated = search.length > 1 && Array.from(search).every((char) => char === search[0]);
|
|
407
|
+
const normalizedSearch = isRepeated ? search[0] : search;
|
|
408
|
+
const currentMatchIndex = currentMatch ? values.indexOf(currentMatch) : -1;
|
|
409
|
+
let wrappedValues = wrapArray(values, Math.max(currentMatchIndex, 0));
|
|
410
|
+
const excludeCurrentMatch = normalizedSearch.length === 1;
|
|
411
|
+
if (excludeCurrentMatch)
|
|
412
|
+
wrappedValues = wrappedValues.filter((v) => v !== currentMatch);
|
|
413
|
+
const nextMatch = wrappedValues.find((value) => value.toLowerCase().startsWith(normalizedSearch.toLowerCase()));
|
|
414
|
+
return nextMatch !== currentMatch ? nextMatch : undefined;
|
|
415
|
+
}
|
|
416
|
+
|
|
336
417
|
const context$1 = () => {
|
|
337
418
|
const context = inject(RdxSelectPopup);
|
|
338
419
|
return {
|
|
@@ -405,7 +486,8 @@ class RdxSelectPopup {
|
|
|
405
486
|
* **ancestor** — can read them without injecting the composite list (which the popup provides as
|
|
406
487
|
* a descendant, so an upward `inject` would not find it).
|
|
407
488
|
*/
|
|
408
|
-
this.items = computed(() => this.compositeList.items(),
|
|
489
|
+
this.items = computed(() => this.compositeList.items(), /* @ts-ignore */
|
|
490
|
+
...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
409
491
|
/**
|
|
410
492
|
* Highlight-model navigation over the collected items (DOM order). `loop` is disabled so arrow
|
|
411
493
|
* navigation stops at the first / last item instead of wrapping around — matching native
|
|
@@ -418,15 +500,23 @@ class RdxSelectPopup {
|
|
|
418
500
|
loop: signal(false),
|
|
419
501
|
injector: this.injector
|
|
420
502
|
});
|
|
421
|
-
this.selectedItem = signal(undefined,
|
|
422
|
-
|
|
423
|
-
this.
|
|
424
|
-
|
|
425
|
-
this.
|
|
503
|
+
this.selectedItem = signal(undefined, /* @ts-ignore */
|
|
504
|
+
...(ngDevMode ? [{ debugName: "selectedItem" }] : /* istanbul ignore next */ []));
|
|
505
|
+
this.selectedItemText = signal(undefined, /* @ts-ignore */
|
|
506
|
+
...(ngDevMode ? [{ debugName: "selectedItemText" }] : /* istanbul ignore next */ []));
|
|
507
|
+
this.firstValidItemFoundRef = signal(false, /* @ts-ignore */
|
|
508
|
+
...(ngDevMode ? [{ debugName: "firstValidItemFoundRef" }] : /* istanbul ignore next */ []));
|
|
509
|
+
this.viewport = signal(undefined, /* @ts-ignore */
|
|
510
|
+
...(ngDevMode ? [{ debugName: "viewport" }] : /* istanbul ignore next */ []));
|
|
511
|
+
this.isPositioned = signal(false, /* @ts-ignore */
|
|
512
|
+
...(ngDevMode ? [{ debugName: "isPositioned" }] : /* istanbul ignore next */ []));
|
|
426
513
|
// Tracks whether the last interaction was the keyboard, so the highlight doesn't jump to an item
|
|
427
514
|
// the cursor happens to rest on when arrow-key navigation scrolls the list.
|
|
428
515
|
this.keyboardActive = false;
|
|
429
516
|
this.hasHighlightedOpen = false;
|
|
517
|
+
// Typeahead buffer (APG listbox): printable characters accumulate for 1s and jump the highlight to
|
|
518
|
+
// the next item whose text matches.
|
|
519
|
+
this.typeaheadSearch = '';
|
|
430
520
|
/**
|
|
431
521
|
* Event handler called when the escape key is down.
|
|
432
522
|
* Can be prevented.
|
|
@@ -437,7 +527,8 @@ class RdxSelectPopup {
|
|
|
437
527
|
* Can be prevented.
|
|
438
528
|
*/
|
|
439
529
|
this.pointerDownOutside = output();
|
|
440
|
-
this.content = signal(null,
|
|
530
|
+
this.content = signal(null, /* @ts-ignore */
|
|
531
|
+
...(ngDevMode ? [{ debugName: "content" }] : /* istanbul ignore next */ []));
|
|
441
532
|
/**
|
|
442
533
|
* The positioner — now an **ancestor** element — provides {@link RDX_SELECT_POSITIONER_TOKEN}
|
|
443
534
|
* (Popper or item-aligned). We react to its `placed` to highlight and scroll the selected item
|
|
@@ -459,6 +550,9 @@ class RdxSelectPopup {
|
|
|
459
550
|
effect(() => {
|
|
460
551
|
if (!this.rootContext.open()) {
|
|
461
552
|
this.hasHighlightedOpen = false;
|
|
553
|
+
// Reset the "first valid item" seed so the next open re-resolves it (otherwise the
|
|
554
|
+
// selected/first-item highlight seed is stale on reopen).
|
|
555
|
+
this.firstValidItemFoundRef.set(false);
|
|
462
556
|
return;
|
|
463
557
|
}
|
|
464
558
|
if (!this.isPositioned() || this.hasHighlightedOpen) {
|
|
@@ -482,7 +576,8 @@ class RdxSelectPopup {
|
|
|
482
576
|
// `modal === false`. The gate keys on `open` (not mounted) so it releases at close-start. A
|
|
483
577
|
// **touch** open never uses item-aligned mode (the positioner falls back), so the lock there is
|
|
484
578
|
// driven by `modal` alone and the anchored helper only engages when the popup is viewport-width (§3).
|
|
485
|
-
const itemAlignedActive = computed(() => this.positioner?.alignItemWithTriggerActive?.() ?? false,
|
|
579
|
+
const itemAlignedActive = computed(() => this.positioner?.alignItemWithTriggerActive?.() ?? false, /* @ts-ignore */
|
|
580
|
+
...(ngDevMode ? [{ debugName: "itemAlignedActive" }] : /* istanbul ignore next */ []));
|
|
486
581
|
useAnchoredScrollLock(computed(() => (itemAlignedActive() || this.rootContext.modal()) && this.rootContext.open()), {
|
|
487
582
|
touchOpen: () => this.rootContext.openedByTouch(),
|
|
488
583
|
element: () => this.currentElement.nativeElement
|
|
@@ -490,6 +585,7 @@ class RdxSelectPopup {
|
|
|
490
585
|
// The popup's animation determines when the open/close transition (onOpenChangeComplete) is done.
|
|
491
586
|
const unregisterTransition = this.rootContext.registerTransitionElement(this.currentElement.nativeElement);
|
|
492
587
|
inject(DestroyRef).onDestroy(unregisterTransition);
|
|
588
|
+
inject(DestroyRef).onDestroy(() => clearTimeout(this.typeaheadTimer));
|
|
493
589
|
// The popup (listbox) is this layer's floating element — the inside surface for containment.
|
|
494
590
|
this.floatingContext.setFloatingElement(this.currentElement.nativeElement);
|
|
495
591
|
// Dismissal (ADR 0015): Escape or an outside press closes the select. Focus-out does NOT close it
|
|
@@ -630,10 +726,36 @@ class RdxSelectPopup {
|
|
|
630
726
|
this.highlight.last();
|
|
631
727
|
break;
|
|
632
728
|
}
|
|
729
|
+
return;
|
|
730
|
+
}
|
|
731
|
+
// Typeahead: a single printable character jumps the highlight to the next matching item.
|
|
732
|
+
if (keyEvent.key.length === 1 && !keyEvent.ctrlKey && !keyEvent.altKey && !keyEvent.metaKey) {
|
|
733
|
+
this.handleTypeahead(keyEvent.key);
|
|
633
734
|
}
|
|
634
735
|
}
|
|
635
|
-
|
|
636
|
-
|
|
736
|
+
/** Accumulates printable keys for 1s and moves the highlight to the next item whose text matches. */
|
|
737
|
+
handleTypeahead(key) {
|
|
738
|
+
this.typeaheadSearch += key;
|
|
739
|
+
clearTimeout(this.typeaheadTimer);
|
|
740
|
+
this.typeaheadTimer = setTimeout(() => (this.typeaheadSearch = ''), 1000);
|
|
741
|
+
const navigableItems = this.items().filter((item) => !item.metadata()?.disabled);
|
|
742
|
+
const values = navigableItems.map((item) => this.itemText(item));
|
|
743
|
+
const current = this.highlight.highlightedItem();
|
|
744
|
+
const nextMatch = getNextMatch(values, this.typeaheadSearch, current ? this.itemText(current) : undefined);
|
|
745
|
+
if (nextMatch === undefined) {
|
|
746
|
+
return;
|
|
747
|
+
}
|
|
748
|
+
const match = navigableItems[values.indexOf(nextMatch)];
|
|
749
|
+
if (match) {
|
|
750
|
+
this.keyboardActive = true;
|
|
751
|
+
this.highlight.set(match);
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
itemText(item) {
|
|
755
|
+
return (item.metadata()?.textValue || item.element.textContent || '').trim();
|
|
756
|
+
}
|
|
757
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectPopup, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
758
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: RdxSelectPopup, isStandalone: true, selector: "[rdxSelectPopup]", outputs: { escapeKeyDown: "escapeKeyDown", pointerDownOutside: "pointerDownOutside" }, host: { attributes: { "role": "listbox", "tabindex": "-1" }, listeners: { "keydown": "handleKeyDown($event)" }, properties: { "id": "rootContext.contentId", "attr.aria-activedescendant": "highlight.activeId()", "attr.aria-multiselectable": "rootContext.multiple() ? \"true\" : undefined", "attr.data-open": "rootContext.open() ? \"\" : undefined", "attr.data-closed": "rootContext.open() ? undefined : \"\"", "attr.data-starting-style": "rootContext.transitionStatus() === \"starting\" ? \"\" : undefined", "attr.data-ending-style": "rootContext.transitionStatus() === \"ending\" ? \"\" : undefined", "dir": "rootContext.dir()", "style": "{\n display: 'flex',\n flexDirection: 'column',\n outline: 'none'\n }" } }, providers: [
|
|
637
759
|
provideSelectPopupContext(context$1),
|
|
638
760
|
provideFloatingFocusManagerConfig(() => {
|
|
639
761
|
const rootContext = injectSelectRootContext();
|
|
@@ -651,7 +773,7 @@ class RdxSelectPopup {
|
|
|
651
773
|
})
|
|
652
774
|
], hostDirectives: [{ directive: i1.RdxPopperContent }, { directive: i2.RdxFloatingFocusManager, inputs: ["returnFocus", "finalFocus"] }, { directive: i3.RdxFloatingNodeRegistration }, { directive: i4.RdxCompositeList }], ngImport: i0 }); }
|
|
653
775
|
}
|
|
654
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
776
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectPopup, decorators: [{
|
|
655
777
|
type: Directive,
|
|
656
778
|
args: [{
|
|
657
779
|
selector: '[rdxSelectPopup]',
|
|
@@ -684,7 +806,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
684
806
|
'[id]': 'rootContext.contentId',
|
|
685
807
|
'[attr.aria-activedescendant]': 'highlight.activeId()',
|
|
686
808
|
'[attr.aria-multiselectable]': 'rootContext.multiple() ? "true" : undefined',
|
|
687
|
-
'[attr.data-state]': 'rootContext.open() ? "open" : "closed"',
|
|
688
809
|
'[attr.data-open]': 'rootContext.open() ? "" : undefined',
|
|
689
810
|
'[attr.data-closed]': 'rootContext.open() ? undefined : ""',
|
|
690
811
|
'[attr.data-starting-style]': 'rootContext.transitionStatus() === "starting" ? "" : undefined',
|
|
@@ -719,13 +840,18 @@ class RdxSelectItem {
|
|
|
719
840
|
this.contentContext = injectSelectPopupContext();
|
|
720
841
|
this.listItem = inject(RdxCompositeListItem, { self: true });
|
|
721
842
|
this.currentElement = inject(ElementRef);
|
|
722
|
-
this.value = input(
|
|
723
|
-
|
|
843
|
+
this.value = input(/* @ts-ignore */
|
|
844
|
+
...(ngDevMode ? [undefined, { debugName: "value" }] : /* istanbul ignore next */ []));
|
|
845
|
+
this.textValue = input('', /* @ts-ignore */
|
|
846
|
+
...(ngDevMode ? [{ debugName: "textValue" }] : /* istanbul ignore next */ []));
|
|
724
847
|
this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
725
|
-
this.textValue$ = linkedSignal(this.textValue,
|
|
726
|
-
|
|
848
|
+
this.textValue$ = linkedSignal(this.textValue, /* @ts-ignore */
|
|
849
|
+
...(ngDevMode ? [{ debugName: "textValue$" }] : /* istanbul ignore next */ []));
|
|
850
|
+
this.isSelected = computed(() => valueComparator(this.rootContext.value(), this.value(), this.rootContext.isItemEqualToValue()), /* @ts-ignore */
|
|
851
|
+
...(ngDevMode ? [{ debugName: "isSelected" }] : /* istanbul ignore next */ []));
|
|
727
852
|
/** Highlighted via the highlight model (keyboard / hover), not DOM focus. */
|
|
728
|
-
this.isHighlighted = computed(() => this.contentContext.isHighlighted(this.currentElement.nativeElement),
|
|
853
|
+
this.isHighlighted = computed(() => this.contentContext.isHighlighted(this.currentElement.nativeElement), /* @ts-ignore */
|
|
854
|
+
...(ngDevMode ? [{ debugName: "isHighlighted" }] : /* istanbul ignore next */ []));
|
|
729
855
|
/** Item id, referenced by the popup's `aria-activedescendant`. */
|
|
730
856
|
this.id = injectId('rdx-select-item-');
|
|
731
857
|
this.textId = injectId('rdx-select-item-text-');
|
|
@@ -780,10 +906,10 @@ class RdxSelectItem {
|
|
|
780
906
|
if (SELECTION_KEYS.includes(keyEvent.key))
|
|
781
907
|
this.onPointerUp(keyEvent);
|
|
782
908
|
}
|
|
783
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
784
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "
|
|
909
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectItem, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
910
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: RdxSelectItem, isStandalone: true, selector: "[rdxSelectItem]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, textValue: { classPropertyName: "textValue", publicName: "textValue", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "option" }, listeners: { "pointerup": "onPointerUp($event)", "pointerleave": "onPointerLeave($event)", "pointermove": "onPointerMove($event)" }, properties: { "attr.id": "id", "attr.aria-selected": "isSelected()", "attr.aria-disabled": "disabled() ? \"true\" : undefined", "attr.data-selected": "isSelected() ? \"\" : undefined", "attr.data-highlighted": "isHighlighted() ? \"\" : undefined", "attr.data-disabled": "disabled() ? \"\" : undefined" } }, providers: [provideSelectItemContext(context)], exportAs: ["rdxSelectItem"], hostDirectives: [{ directive: i4.RdxCompositeListItem }], ngImport: i0 }); }
|
|
785
911
|
}
|
|
786
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
912
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectItem, decorators: [{
|
|
787
913
|
type: Directive,
|
|
788
914
|
args: [{
|
|
789
915
|
selector: '[rdxSelectItem]',
|
|
@@ -795,7 +921,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
795
921
|
'[attr.id]': 'id',
|
|
796
922
|
'[attr.aria-selected]': 'isSelected()',
|
|
797
923
|
'[attr.aria-disabled]': 'disabled() ? "true" : undefined',
|
|
798
|
-
'[attr.data-state]': 'isSelected() ? "checked" : "unchecked"',
|
|
799
924
|
'[attr.data-selected]': 'isSelected() ? "" : undefined',
|
|
800
925
|
'[attr.data-highlighted]': 'isHighlighted() ? "" : undefined',
|
|
801
926
|
'[attr.data-disabled]': 'disabled() ? "" : undefined',
|
|
@@ -806,14 +931,233 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
806
931
|
}]
|
|
807
932
|
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], textValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "textValue", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
|
|
808
933
|
|
|
934
|
+
class RdxSelectItemAlignedPositionContent {
|
|
935
|
+
constructor() {
|
|
936
|
+
this.currentElementRef = inject(ElementRef);
|
|
937
|
+
}
|
|
938
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectItemAlignedPositionContent, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
939
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: RdxSelectItemAlignedPositionContent, isStandalone: true, selector: "[rdxSelectItemAlignedPositionContent]", host: { properties: { "style": "{\n boxSizing: 'border-box',\n display: 'flex',\n flexDirection: 'column'\n }" } }, ngImport: i0 }); }
|
|
940
|
+
}
|
|
941
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectItemAlignedPositionContent, decorators: [{
|
|
942
|
+
type: Directive,
|
|
943
|
+
args: [{
|
|
944
|
+
selector: '[rdxSelectItemAlignedPositionContent]',
|
|
945
|
+
host: {
|
|
946
|
+
'[style]': `{
|
|
947
|
+
boxSizing: 'border-box',
|
|
948
|
+
display: 'flex',
|
|
949
|
+
flexDirection: 'column'
|
|
950
|
+
}`
|
|
951
|
+
}
|
|
952
|
+
}]
|
|
953
|
+
}] });
|
|
954
|
+
|
|
955
|
+
class RdxSelectItemAlignedPosition {
|
|
956
|
+
constructor() {
|
|
957
|
+
this.currentElement = inject(ElementRef);
|
|
958
|
+
this.rootContext = injectSelectRootContext();
|
|
959
|
+
/**
|
|
960
|
+
* The popup is now a **descendant** (item-aligned-position is the outer positioner), so read the
|
|
961
|
+
* viewport / selected-item measurements off the popup instance instead of injecting its context.
|
|
962
|
+
*/
|
|
963
|
+
this.popup = contentChild.required(RdxSelectPopup);
|
|
964
|
+
this.placed = output();
|
|
965
|
+
/**
|
|
966
|
+
* Whether item-aligned positioning is active (Base UI `alignItemWithTriggerActive`): open **and not**
|
|
967
|
+
* touch-opened. A touch open falls back to a plain anchored dropdown ({@link positionBelowTrigger}).
|
|
968
|
+
* Read by the popup's scroll-lock policy — an active item-aligned popup locks even when `modal=false`.
|
|
969
|
+
*/
|
|
970
|
+
this.alignItemWithTriggerActive = computed(() => this.rootContext.open() && !this.rootContext.openedByTouch(), /* @ts-ignore */
|
|
971
|
+
...(ngDevMode ? [{ debugName: "alignItemWithTriggerActive" }] : /* istanbul ignore next */ []));
|
|
972
|
+
this.contentZIndex = signal('', /* @ts-ignore */
|
|
973
|
+
...(ngDevMode ? [{ debugName: "contentZIndex" }] : /* istanbul ignore next */ []));
|
|
974
|
+
this.shouldExpandOnScrollRef = signal(false, /* @ts-ignore */
|
|
975
|
+
...(ngDevMode ? [{ debugName: "shouldExpandOnScrollRef" }] : /* istanbul ignore next */ []));
|
|
976
|
+
this.contentWrapperElement = signal(this.currentElement.nativeElement, /* @ts-ignore */
|
|
977
|
+
...(ngDevMode ? [{ debugName: "contentWrapperElement" }] : /* istanbul ignore next */ []));
|
|
978
|
+
this.contentElement = contentChild.required(RdxSelectItemAlignedPositionContent);
|
|
979
|
+
afterNextRender(() => {
|
|
980
|
+
this.position();
|
|
981
|
+
if (this.contentElement().currentElementRef.nativeElement) {
|
|
982
|
+
this.contentZIndex.set(window.getComputedStyle(this.contentElement().currentElementRef.nativeElement).zIndex);
|
|
983
|
+
}
|
|
984
|
+
});
|
|
985
|
+
const injector = inject(Injector);
|
|
986
|
+
// Resize and position when trigger element changes
|
|
987
|
+
resizeEffect({
|
|
988
|
+
injector,
|
|
989
|
+
element: this.rootContext.triggerElement,
|
|
990
|
+
onResize: () => this.position()
|
|
991
|
+
});
|
|
992
|
+
}
|
|
993
|
+
position() {
|
|
994
|
+
// Base UI parity: a touch-opened select does NOT align the item with the trigger (the macOS-style
|
|
995
|
+
// overlay is awkward on mobile). Fall back to a plain anchored dropdown below the trigger.
|
|
996
|
+
if (!this.alignItemWithTriggerActive()) {
|
|
997
|
+
this.positionBelowTrigger();
|
|
998
|
+
return;
|
|
999
|
+
}
|
|
1000
|
+
if (this.rootContext.triggerElement() &&
|
|
1001
|
+
this.rootContext.valueElement() &&
|
|
1002
|
+
this.contentWrapperElement() &&
|
|
1003
|
+
this.contentElement().currentElementRef.nativeElement &&
|
|
1004
|
+
this.popup().viewport() &&
|
|
1005
|
+
this.popup().selectedItem() &&
|
|
1006
|
+
this.popup().selectedItemText()) {
|
|
1007
|
+
const triggerRect = this.rootContext.triggerElement().getBoundingClientRect();
|
|
1008
|
+
// -----------------------------------------------------------------------------------------
|
|
1009
|
+
// Horizontal positioning
|
|
1010
|
+
// -----------------------------------------------------------------------------------------
|
|
1011
|
+
const contentRect = this.currentElement.nativeElement.getBoundingClientRect();
|
|
1012
|
+
const valueNodeRect = this.rootContext.valueElement().getBoundingClientRect();
|
|
1013
|
+
const itemTextRect = this.popup().selectedItemText().getBoundingClientRect();
|
|
1014
|
+
if (this.rootContext.dir() !== 'rtl') {
|
|
1015
|
+
const itemTextOffset = itemTextRect.left - contentRect.left;
|
|
1016
|
+
const left = valueNodeRect.left - itemTextOffset;
|
|
1017
|
+
const leftDelta = triggerRect.left - left;
|
|
1018
|
+
const minContentWidth = triggerRect.width + leftDelta;
|
|
1019
|
+
const contentWidth = Math.max(minContentWidth, contentRect.width);
|
|
1020
|
+
const rightEdge = window.innerWidth - CONTENT_MARGIN;
|
|
1021
|
+
const clampedLeft = clamp(left, CONTENT_MARGIN, Math.max(CONTENT_MARGIN, rightEdge - contentWidth));
|
|
1022
|
+
this.contentWrapperElement().style.minWidth = `${minContentWidth}px`;
|
|
1023
|
+
this.contentWrapperElement().style.left = `${clampedLeft}px`;
|
|
1024
|
+
}
|
|
1025
|
+
else {
|
|
1026
|
+
const itemTextOffset = contentRect.right - itemTextRect.right;
|
|
1027
|
+
const right = window.innerWidth - valueNodeRect.right - itemTextOffset;
|
|
1028
|
+
const rightDelta = window.innerWidth - triggerRect.right - right;
|
|
1029
|
+
const minContentWidth = triggerRect.width + rightDelta;
|
|
1030
|
+
const contentWidth = Math.max(minContentWidth, contentRect.width);
|
|
1031
|
+
const leftEdge = window.innerWidth - CONTENT_MARGIN;
|
|
1032
|
+
const clampedRight = clamp(right, CONTENT_MARGIN, Math.max(CONTENT_MARGIN, leftEdge - contentWidth));
|
|
1033
|
+
this.contentWrapperElement().style.minWidth = `${minContentWidth}px`;
|
|
1034
|
+
this.contentWrapperElement().style.right = `${clampedRight}px`;
|
|
1035
|
+
}
|
|
1036
|
+
// -----------------------------------------------------------------------------------------
|
|
1037
|
+
// Vertical positioning
|
|
1038
|
+
// -----------------------------------------------------------------------------------------
|
|
1039
|
+
const items = this.popup()
|
|
1040
|
+
.items()
|
|
1041
|
+
.map((i) => i.element);
|
|
1042
|
+
const availableHeight = window.innerHeight - CONTENT_MARGIN * 2;
|
|
1043
|
+
const itemsHeight = this.popup().viewport().scrollHeight;
|
|
1044
|
+
const contentStyles = window.getComputedStyle(this.currentElement.nativeElement);
|
|
1045
|
+
const contentBorderTopWidth = Number.parseInt(contentStyles.borderTopWidth, 10);
|
|
1046
|
+
const contentPaddingTop = Number.parseInt(contentStyles.paddingTop, 10);
|
|
1047
|
+
const contentBorderBottomWidth = Number.parseInt(contentStyles.borderBottomWidth, 10);
|
|
1048
|
+
const contentPaddingBottom = Number.parseInt(contentStyles.paddingBottom, 10);
|
|
1049
|
+
const fullContentHeight = contentBorderTopWidth +
|
|
1050
|
+
contentPaddingTop +
|
|
1051
|
+
itemsHeight +
|
|
1052
|
+
contentPaddingBottom +
|
|
1053
|
+
contentBorderBottomWidth;
|
|
1054
|
+
const minContentHeight = Math.min(this.popup().selectedItem().offsetHeight * 5, fullContentHeight);
|
|
1055
|
+
const viewportStyles = window.getComputedStyle(this.popup().viewport());
|
|
1056
|
+
const viewportPaddingTop = Number.parseInt(viewportStyles.paddingTop, 10);
|
|
1057
|
+
const viewportPaddingBottom = Number.parseInt(viewportStyles.paddingBottom, 10);
|
|
1058
|
+
const topEdgeToTriggerMiddle = triggerRect.top + triggerRect.height / 2 - CONTENT_MARGIN;
|
|
1059
|
+
const triggerMiddleToBottomEdge = availableHeight - topEdgeToTriggerMiddle;
|
|
1060
|
+
const selectedItemHalfHeight = this.popup().selectedItem().offsetHeight / 2;
|
|
1061
|
+
const itemOffsetMiddle = this.popup().selectedItem().offsetTop + selectedItemHalfHeight;
|
|
1062
|
+
const contentTopToItemMiddle = contentBorderTopWidth + contentPaddingTop + itemOffsetMiddle;
|
|
1063
|
+
const itemMiddleToContentBottom = fullContentHeight - contentTopToItemMiddle;
|
|
1064
|
+
const willAlignWithoutTopOverflow = contentTopToItemMiddle <= topEdgeToTriggerMiddle;
|
|
1065
|
+
if (willAlignWithoutTopOverflow) {
|
|
1066
|
+
const isLastItem = this.popup().selectedItem() === items[items.length - 1];
|
|
1067
|
+
this.contentWrapperElement().style.bottom = `${0}px`;
|
|
1068
|
+
const viewportOffsetBottom = this.currentElement.nativeElement.clientHeight -
|
|
1069
|
+
this.popup().viewport().offsetTop -
|
|
1070
|
+
this.popup().viewport().offsetHeight;
|
|
1071
|
+
const clampedTriggerMiddleToBottomEdge = Math.max(triggerMiddleToBottomEdge, selectedItemHalfHeight +
|
|
1072
|
+
// viewport might have padding bottom, include it to avoid a scrollable viewport
|
|
1073
|
+
(isLastItem ? viewportPaddingBottom : 0) +
|
|
1074
|
+
viewportOffsetBottom +
|
|
1075
|
+
contentBorderBottomWidth);
|
|
1076
|
+
const height = contentTopToItemMiddle + clampedTriggerMiddleToBottomEdge;
|
|
1077
|
+
this.contentWrapperElement().style.height = `${height}px`;
|
|
1078
|
+
}
|
|
1079
|
+
else {
|
|
1080
|
+
const isFirstItem = this.popup().selectedItem() === items[0];
|
|
1081
|
+
this.contentWrapperElement().style.top = `${0}px`;
|
|
1082
|
+
const clampedTopEdgeToTriggerMiddle = Math.max(topEdgeToTriggerMiddle, contentBorderTopWidth +
|
|
1083
|
+
this.popup().viewport().offsetTop +
|
|
1084
|
+
// viewport might have padding top, include it to avoid a scrollable viewport
|
|
1085
|
+
(isFirstItem ? viewportPaddingTop : 0) +
|
|
1086
|
+
selectedItemHalfHeight);
|
|
1087
|
+
const height = clampedTopEdgeToTriggerMiddle + itemMiddleToContentBottom;
|
|
1088
|
+
this.contentWrapperElement().style.height = `${height}px`;
|
|
1089
|
+
this.popup().viewport().scrollTop =
|
|
1090
|
+
contentTopToItemMiddle - topEdgeToTriggerMiddle + this.popup().viewport().offsetTop;
|
|
1091
|
+
}
|
|
1092
|
+
this.contentWrapperElement().style.margin = `${CONTENT_MARGIN}px 0`;
|
|
1093
|
+
this.contentWrapperElement().style.minHeight = `${minContentHeight}px`;
|
|
1094
|
+
this.contentWrapperElement().style.maxHeight = `${availableHeight}px`;
|
|
1095
|
+
// -----------------------------------------------------------------------------------------
|
|
1096
|
+
this.placed.emit();
|
|
1097
|
+
// we don't want the initial scroll position adjustment to trigger "expand on scroll"
|
|
1098
|
+
// so we explicitly turn it on only after they've registered.
|
|
1099
|
+
requestAnimationFrame(() => this.shouldExpandOnScrollRef.set(true));
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
/**
|
|
1103
|
+
* Touch fallback (Base UI disables item-alignment on touch): position the popup as a plain anchored
|
|
1104
|
+
* dropdown just below the trigger, clamped to the viewport, with no item alignment or pre-scroll.
|
|
1105
|
+
*/
|
|
1106
|
+
positionBelowTrigger() {
|
|
1107
|
+
const trigger = this.rootContext.triggerElement();
|
|
1108
|
+
const wrapper = this.contentWrapperElement();
|
|
1109
|
+
if (!trigger || !wrapper) {
|
|
1110
|
+
return;
|
|
1111
|
+
}
|
|
1112
|
+
const triggerRect = trigger.getBoundingClientRect();
|
|
1113
|
+
const availableHeight = window.innerHeight - CONTENT_MARGIN * 2;
|
|
1114
|
+
const maxLeft = Math.max(CONTENT_MARGIN, window.innerWidth - CONTENT_MARGIN - triggerRect.width);
|
|
1115
|
+
wrapper.style.left = `${clamp(triggerRect.left, CONTENT_MARGIN, maxLeft)}px`;
|
|
1116
|
+
wrapper.style.top = `${triggerRect.bottom}px`;
|
|
1117
|
+
wrapper.style.bottom = '';
|
|
1118
|
+
wrapper.style.height = '';
|
|
1119
|
+
wrapper.style.margin = `${CONTENT_MARGIN}px 0`;
|
|
1120
|
+
wrapper.style.minWidth = `${triggerRect.width}px`;
|
|
1121
|
+
wrapper.style.maxHeight = `${availableHeight}px`;
|
|
1122
|
+
this.placed.emit();
|
|
1123
|
+
}
|
|
1124
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectItemAlignedPosition, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1125
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "22.0.2", type: RdxSelectItemAlignedPosition, isStandalone: true, selector: "[rdxSelectItemAlignedPosition]", outputs: { placed: "placed" }, host: { properties: { "style": "{\n display: 'flex',\n flexDirection: 'column',\n position: 'fixed',\n zIndex: contentZIndex(),\n }" } }, providers: [
|
|
1126
|
+
{
|
|
1127
|
+
provide: RDX_SELECT_POSITIONER_TOKEN,
|
|
1128
|
+
useExisting: forwardRef(() => RdxSelectItemAlignedPosition)
|
|
1129
|
+
}
|
|
1130
|
+
], queries: [{ propertyName: "popup", first: true, predicate: RdxSelectPopup, descendants: true, isSignal: true }, { propertyName: "contentElement", first: true, predicate: RdxSelectItemAlignedPositionContent, descendants: true, isSignal: true }], ngImport: i0 }); }
|
|
1131
|
+
}
|
|
1132
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectItemAlignedPosition, decorators: [{
|
|
1133
|
+
type: Directive,
|
|
1134
|
+
args: [{
|
|
1135
|
+
selector: '[rdxSelectItemAlignedPosition]',
|
|
1136
|
+
providers: [
|
|
1137
|
+
{
|
|
1138
|
+
provide: RDX_SELECT_POSITIONER_TOKEN,
|
|
1139
|
+
useExisting: forwardRef(() => RdxSelectItemAlignedPosition)
|
|
1140
|
+
}
|
|
1141
|
+
],
|
|
1142
|
+
host: {
|
|
1143
|
+
'[style]': `{
|
|
1144
|
+
display: 'flex',
|
|
1145
|
+
flexDirection: 'column',
|
|
1146
|
+
position: 'fixed',
|
|
1147
|
+
zIndex: contentZIndex(),
|
|
1148
|
+
}`
|
|
1149
|
+
}
|
|
1150
|
+
}]
|
|
1151
|
+
}], ctorParameters: () => [], propDecorators: { popup: [{ type: i0.ContentChild, args: [i0.forwardRef(() => RdxSelectPopup), { isSignal: true }] }], placed: [{ type: i0.Output, args: ["placed"] }], contentElement: [{ type: i0.ContentChild, args: [i0.forwardRef(() => RdxSelectItemAlignedPositionContent), { isSignal: true }] }] } });
|
|
1152
|
+
|
|
809
1153
|
class RdxSelectItemIndicator {
|
|
810
1154
|
constructor() {
|
|
811
1155
|
this.itemContext = injectSelectItemContext();
|
|
812
1156
|
}
|
|
813
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
814
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
1157
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectItemIndicator, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1158
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: RdxSelectItemIndicator, isStandalone: true, selector: "[rdxSelectItemIndicator]", host: { properties: { "attr.aria-hidden": "true", "hidden": "!itemContext.isSelected()" } }, ngImport: i0 }); }
|
|
815
1159
|
}
|
|
816
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1160
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectItemIndicator, decorators: [{
|
|
817
1161
|
type: Directive,
|
|
818
1162
|
args: [{
|
|
819
1163
|
selector: '[rdxSelectItemIndicator]',
|
|
@@ -836,7 +1180,8 @@ class RdxSelectItemText {
|
|
|
836
1180
|
disabled: this.itemContext.disabled(),
|
|
837
1181
|
textContent: this.elementRef.nativeElement.textContent ?? this.itemContext.value()?.toString() ?? ''
|
|
838
1182
|
};
|
|
839
|
-
},
|
|
1183
|
+
}, /* @ts-ignore */
|
|
1184
|
+
...(ngDevMode ? [{ debugName: "optionProps" }] : /* istanbul ignore next */ []));
|
|
840
1185
|
afterNextRender(() => {
|
|
841
1186
|
this.itemContext.onItemTextChange(this.elementRef.nativeElement);
|
|
842
1187
|
this.contentContext.itemTextRefCallback(this.elementRef.nativeElement, this.itemContext.value(), this.itemContext.disabled());
|
|
@@ -847,10 +1192,10 @@ class RdxSelectItemText {
|
|
|
847
1192
|
this.rootContext.onOptionRemove(this.optionProps);
|
|
848
1193
|
});
|
|
849
1194
|
}
|
|
850
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
851
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
1195
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectItemText, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1196
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: RdxSelectItemText, isStandalone: true, selector: "[rdxSelectItemText]", host: { properties: { "id": "itemContext.textId" } }, ngImport: i0 }); }
|
|
852
1197
|
}
|
|
853
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1198
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectItemText, decorators: [{
|
|
854
1199
|
type: Directive,
|
|
855
1200
|
args: [{
|
|
856
1201
|
selector: '[rdxSelectItemText]',
|
|
@@ -864,7 +1209,8 @@ class RdxSelectList {
|
|
|
864
1209
|
constructor() {
|
|
865
1210
|
this.contentContext = injectSelectPopupContext();
|
|
866
1211
|
this.elementRef = inject((ElementRef));
|
|
867
|
-
this.prevScrollTopRef = signal(0,
|
|
1212
|
+
this.prevScrollTopRef = signal(0, /* @ts-ignore */
|
|
1213
|
+
...(ngDevMode ? [{ debugName: "prevScrollTopRef" }] : /* istanbul ignore next */ []));
|
|
868
1214
|
afterNextRender(() => {
|
|
869
1215
|
this.contentContext?.onViewportChange(this.elementRef.nativeElement);
|
|
870
1216
|
});
|
|
@@ -873,10 +1219,10 @@ class RdxSelectList {
|
|
|
873
1219
|
const viewport = event.currentTarget;
|
|
874
1220
|
this.prevScrollTopRef.set(viewport.scrollTop);
|
|
875
1221
|
}
|
|
876
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
877
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
1222
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectList, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1223
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: RdxSelectList, isStandalone: true, selector: "[rdxSelectList]", host: { attributes: { "role": "presentation" }, listeners: { "scroll": "handleScroll($event)" }, properties: { "attr.data-rdx-select-list": "\"\"", "style": "{\n position: 'relative',\n flex: 1,\n overflow: 'hidden auto',\n scrollbarWidth: 'none'\n }" } }, ngImport: i0 }); }
|
|
878
1224
|
}
|
|
879
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1225
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectList, decorators: [{
|
|
880
1226
|
type: Directive,
|
|
881
1227
|
args: [{
|
|
882
1228
|
selector: '[rdxSelectList]',
|
|
@@ -904,10 +1250,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
904
1250
|
* `document.body` while the select is closed.
|
|
905
1251
|
*/
|
|
906
1252
|
class RdxSelectPortal {
|
|
907
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
908
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
1253
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectPortal, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1254
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: RdxSelectPortal, isStandalone: true, selector: "ng-template[rdxSelectPortal]", providers: [provideRdxPresenceContext(() => ({ present: injectSelectRootContext().open }))], exportAs: ["rdxSelectPortal"], hostDirectives: [{ directive: i1$1.RdxPortalPresence, inputs: ["container", "container"] }], ngImport: i0 }); }
|
|
909
1255
|
}
|
|
910
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1256
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectPortal, decorators: [{
|
|
911
1257
|
type: Directive,
|
|
912
1258
|
args: [{
|
|
913
1259
|
selector: 'ng-template[rdxSelectPortal]',
|
|
@@ -929,10 +1275,10 @@ class RdxSelectPortalMisuseGuard {
|
|
|
929
1275
|
'rdxSelectPortalPresence has been removed.', 'components/select');
|
|
930
1276
|
}
|
|
931
1277
|
}
|
|
932
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
933
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
1278
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectPortalMisuseGuard, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1279
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: RdxSelectPortalMisuseGuard, isStandalone: true, selector: "[rdxSelectPortal]:not(ng-template)", ngImport: i0 }); }
|
|
934
1280
|
}
|
|
935
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1281
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectPortalMisuseGuard, decorators: [{
|
|
936
1282
|
type: Directive,
|
|
937
1283
|
args: [{
|
|
938
1284
|
selector: '[rdxSelectPortal]:not(ng-template)'
|
|
@@ -963,14 +1309,14 @@ class RdxSelectPositioner extends RdxPopperContentWrapper {
|
|
|
963
1309
|
cutout: () => rootContext.triggerElement()
|
|
964
1310
|
}));
|
|
965
1311
|
}
|
|
966
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
967
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
1312
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectPositioner, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1313
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: RdxSelectPositioner, isStandalone: true, selector: "[rdxSelectPositioner]", host: { properties: { "style": "positionerStyle" } }, providers: [
|
|
968
1314
|
...provideRdxPopperContentWrapper(RdxSelectPositioner),
|
|
969
1315
|
provideRdxPopperContentConfig({ align: 'start', updatePositionStrategy: 'always' }),
|
|
970
1316
|
{ provide: RDX_SELECT_POSITIONER_TOKEN, useExisting: forwardRef(() => RdxSelectPositioner) }
|
|
971
1317
|
], usesInheritance: true, ngImport: i0 }); }
|
|
972
1318
|
}
|
|
973
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1319
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectPositioner, decorators: [{
|
|
974
1320
|
type: Directive,
|
|
975
1321
|
args: [{
|
|
976
1322
|
selector: '[rdxSelectPositioner]',
|
|
@@ -987,16 +1333,146 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
987
1333
|
}]
|
|
988
1334
|
}], ctorParameters: () => [] });
|
|
989
1335
|
|
|
1336
|
+
class RdxSelectScrollButtonBase {
|
|
1337
|
+
constructor() {
|
|
1338
|
+
this.contentContext = injectSelectPopupContext();
|
|
1339
|
+
this.autoScrollTimerRef = signal(null, /* @ts-ignore */
|
|
1340
|
+
...(ngDevMode ? [{ debugName: "autoScrollTimerRef" }] : /* istanbul ignore next */ []));
|
|
1341
|
+
this.autoScroll = output();
|
|
1342
|
+
effect(() => {
|
|
1343
|
+
this.contentContext.highlightedItem()?.element.scrollIntoView({ block: 'nearest' });
|
|
1344
|
+
});
|
|
1345
|
+
inject(DestroyRef).onDestroy(() => {
|
|
1346
|
+
this.clearAutoScrollTimer();
|
|
1347
|
+
});
|
|
1348
|
+
}
|
|
1349
|
+
clearAutoScrollTimer() {
|
|
1350
|
+
if (this.autoScrollTimerRef() !== null) {
|
|
1351
|
+
window.clearInterval(this.autoScrollTimerRef());
|
|
1352
|
+
this.autoScrollTimerRef.set(null);
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
handlePointerDown() {
|
|
1356
|
+
if (this.autoScrollTimerRef() === null) {
|
|
1357
|
+
this.autoScrollTimerRef.set(window.setInterval(() => {
|
|
1358
|
+
this.autoScroll.emit();
|
|
1359
|
+
}, 50));
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
handlePointerMove() {
|
|
1363
|
+
this.contentContext.onItemLeave?.();
|
|
1364
|
+
if (this.autoScrollTimerRef() === null) {
|
|
1365
|
+
this.autoScrollTimerRef.set(window.setInterval(() => {
|
|
1366
|
+
this.autoScroll.emit();
|
|
1367
|
+
}, 50));
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectScrollButtonBase, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1371
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: RdxSelectScrollButtonBase, isStandalone: true, selector: "[rdxSelectScrollButtonBase]", outputs: { autoScroll: "autoScroll" }, host: { listeners: { "pointerdown": "handlePointerDown()", "pointermove": "handlePointerMove()", "pointerleave": "clearAutoScrollTimer()" }, properties: { "attr.aria-hidden": "true", "style": "{\n flexShrink: 0\n }" } }, ngImport: i0 }); }
|
|
1372
|
+
}
|
|
1373
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectScrollButtonBase, decorators: [{
|
|
1374
|
+
type: Directive,
|
|
1375
|
+
args: [{
|
|
1376
|
+
selector: '[rdxSelectScrollButtonBase]',
|
|
1377
|
+
host: {
|
|
1378
|
+
'[attr.aria-hidden]': 'true',
|
|
1379
|
+
'(pointerdown)': 'handlePointerDown()',
|
|
1380
|
+
'(pointermove)': 'handlePointerMove()',
|
|
1381
|
+
'(pointerleave)': 'clearAutoScrollTimer()',
|
|
1382
|
+
'[style]': `{
|
|
1383
|
+
flexShrink: 0
|
|
1384
|
+
}`
|
|
1385
|
+
}
|
|
1386
|
+
}]
|
|
1387
|
+
}], ctorParameters: () => [], propDecorators: { autoScroll: [{ type: i0.Output, args: ["autoScroll"] }] } });
|
|
1388
|
+
|
|
1389
|
+
class RdxSelectScrollDownButton {
|
|
1390
|
+
constructor() {
|
|
1391
|
+
this.contentContext = injectSelectPopupContext();
|
|
1392
|
+
this.canScrollDown = signal(false, /* @ts-ignore */
|
|
1393
|
+
...(ngDevMode ? [{ debugName: "canScrollDown" }] : /* istanbul ignore next */ []));
|
|
1394
|
+
inject(RdxSelectScrollButtonBase).autoScroll.subscribe(() => {
|
|
1395
|
+
const { viewport, selectedItem } = this.contentContext;
|
|
1396
|
+
if (viewport() && selectedItem()) {
|
|
1397
|
+
viewport().scrollTop = viewport().scrollTop + selectedItem().offsetHeight;
|
|
1398
|
+
}
|
|
1399
|
+
});
|
|
1400
|
+
effect((cleanup) => {
|
|
1401
|
+
if (this.contentContext.viewport() && this.contentContext.isPositioned()) {
|
|
1402
|
+
const viewport = this.contentContext.viewport();
|
|
1403
|
+
const handleScroll = () => {
|
|
1404
|
+
const maxScroll = viewport.scrollHeight - viewport.clientHeight;
|
|
1405
|
+
// we use Math.ceil here because if the UI is zoomed-in
|
|
1406
|
+
// `scrollTop` is not always reported as an integer
|
|
1407
|
+
this.canScrollDown.set(Math.ceil(viewport.scrollTop) < maxScroll);
|
|
1408
|
+
};
|
|
1409
|
+
handleScroll();
|
|
1410
|
+
viewport.addEventListener('scroll', handleScroll);
|
|
1411
|
+
cleanup(() => viewport.removeEventListener('scroll', handleScroll));
|
|
1412
|
+
}
|
|
1413
|
+
});
|
|
1414
|
+
}
|
|
1415
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectScrollDownButton, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1416
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: RdxSelectScrollDownButton, isStandalone: true, selector: "[rdxSelectScrollDownButton]", host: { properties: { "hidden": "!canScrollDown()" } }, hostDirectives: [{ directive: RdxSelectScrollButtonBase }], ngImport: i0 }); }
|
|
1417
|
+
}
|
|
1418
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectScrollDownButton, decorators: [{
|
|
1419
|
+
type: Directive,
|
|
1420
|
+
args: [{
|
|
1421
|
+
selector: '[rdxSelectScrollDownButton]',
|
|
1422
|
+
hostDirectives: [RdxSelectScrollButtonBase],
|
|
1423
|
+
host: {
|
|
1424
|
+
'[hidden]': '!canScrollDown()'
|
|
1425
|
+
}
|
|
1426
|
+
}]
|
|
1427
|
+
}], ctorParameters: () => [] });
|
|
1428
|
+
|
|
1429
|
+
class RdxSelectScrollUpButton {
|
|
1430
|
+
constructor() {
|
|
1431
|
+
this.contentContext = injectSelectPopupContext();
|
|
1432
|
+
this.canScrollUp = signal(false, /* @ts-ignore */
|
|
1433
|
+
...(ngDevMode ? [{ debugName: "canScrollUp" }] : /* istanbul ignore next */ []));
|
|
1434
|
+
inject(RdxSelectScrollButtonBase).autoScroll.subscribe(() => {
|
|
1435
|
+
const { viewport, selectedItem } = this.contentContext;
|
|
1436
|
+
if (viewport() && selectedItem()) {
|
|
1437
|
+
viewport().scrollTop = viewport().scrollTop - selectedItem().offsetHeight;
|
|
1438
|
+
}
|
|
1439
|
+
});
|
|
1440
|
+
effect((cleanup) => {
|
|
1441
|
+
if (this.contentContext.viewport() && this.contentContext.isPositioned()) {
|
|
1442
|
+
const viewport = this.contentContext.viewport();
|
|
1443
|
+
const handleScroll = () => {
|
|
1444
|
+
this.canScrollUp.set(viewport.scrollTop > 0);
|
|
1445
|
+
};
|
|
1446
|
+
handleScroll();
|
|
1447
|
+
viewport.addEventListener('scroll', handleScroll);
|
|
1448
|
+
cleanup(() => viewport.removeEventListener('scroll', handleScroll));
|
|
1449
|
+
}
|
|
1450
|
+
});
|
|
1451
|
+
}
|
|
1452
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectScrollUpButton, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1453
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: RdxSelectScrollUpButton, isStandalone: true, selector: "[rdxSelectScrollUpButton]", host: { properties: { "hidden": "!canScrollUp()" } }, hostDirectives: [{ directive: RdxSelectScrollButtonBase }], ngImport: i0 }); }
|
|
1454
|
+
}
|
|
1455
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectScrollUpButton, decorators: [{
|
|
1456
|
+
type: Directive,
|
|
1457
|
+
args: [{
|
|
1458
|
+
selector: '[rdxSelectScrollUpButton]',
|
|
1459
|
+
hostDirectives: [RdxSelectScrollButtonBase],
|
|
1460
|
+
host: {
|
|
1461
|
+
'[hidden]': '!canScrollUp()'
|
|
1462
|
+
}
|
|
1463
|
+
}]
|
|
1464
|
+
}], ctorParameters: () => [] });
|
|
1465
|
+
|
|
990
1466
|
/**
|
|
991
1467
|
* A visual divider between groups of items.
|
|
992
1468
|
*
|
|
993
1469
|
* @group Components
|
|
994
1470
|
*/
|
|
995
1471
|
class RdxSelectSeparator {
|
|
996
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
997
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "
|
|
1472
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectSeparator, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1473
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: RdxSelectSeparator, isStandalone: true, selector: "[rdxSelectSeparator]", host: { attributes: { "role": "separator", "aria-hidden": "true" } }, exportAs: ["rdxSelectSeparator"], ngImport: i0 }); }
|
|
998
1474
|
}
|
|
999
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1475
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectSeparator, decorators: [{
|
|
1000
1476
|
type: Directive,
|
|
1001
1477
|
args: [{
|
|
1002
1478
|
selector: '[rdxSelectSeparator]',
|
|
@@ -1015,9 +1491,11 @@ class RdxSelectTrigger {
|
|
|
1015
1491
|
this.elementRef = inject(ElementRef);
|
|
1016
1492
|
this.fieldRootContext = injectFieldRootContext(true);
|
|
1017
1493
|
/** The trigger id; Field labels and descriptions reference it for accessible relationships. */
|
|
1018
|
-
this.id = input(injectId('rdx-select-trigger-'),
|
|
1494
|
+
this.id = input(injectId('rdx-select-trigger-'), /* @ts-ignore */
|
|
1495
|
+
...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
1019
1496
|
this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
1020
|
-
this.isDisabled = computed(() => this.rootContext.disabled() || this.disabled() || Boolean(this.fieldRootContext?.disabledState()),
|
|
1497
|
+
this.isDisabled = computed(() => this.rootContext.disabled() || this.disabled() || Boolean(this.fieldRootContext?.disabledState()), /* @ts-ignore */
|
|
1498
|
+
...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
|
|
1021
1499
|
this.triggerInteraction = createRdxTriggerInteraction({
|
|
1022
1500
|
trigger: () => this.elementRef.nativeElement,
|
|
1023
1501
|
activeTrigger: () => this.rootContext.triggerElement(),
|
|
@@ -1025,10 +1503,16 @@ class RdxSelectTrigger {
|
|
|
1025
1503
|
disabled: () => this.isDisabled(),
|
|
1026
1504
|
contentId: () => this.rootContext.contentId
|
|
1027
1505
|
});
|
|
1028
|
-
this.invalidState = computed(() => Boolean(this.fieldRootContext?.invalidState()),
|
|
1029
|
-
|
|
1030
|
-
this.
|
|
1031
|
-
|
|
1506
|
+
this.invalidState = computed(() => Boolean(this.fieldRootContext?.invalidState()), /* @ts-ignore */
|
|
1507
|
+
...(ngDevMode ? [{ debugName: "invalidState" }] : /* istanbul ignore next */ []));
|
|
1508
|
+
this.requiredState = computed(() => this.rootContext.required() || Boolean(this.fieldRootContext?.requiredState()), /* @ts-ignore */
|
|
1509
|
+
...(ngDevMode ? [{ debugName: "requiredState" }] : /* istanbul ignore next */ []));
|
|
1510
|
+
this.readOnlyState = computed(() => this.rootContext.readOnly(), /* @ts-ignore */
|
|
1511
|
+
...(ngDevMode ? [{ debugName: "readOnlyState" }] : /* istanbul ignore next */ []));
|
|
1512
|
+
this.filledState = computed(() => !this.rootContext.isEmptyModelValue() || Boolean(this.fieldRootContext?.filledState()), /* @ts-ignore */
|
|
1513
|
+
...(ngDevMode ? [{ debugName: "filledState" }] : /* istanbul ignore next */ []));
|
|
1514
|
+
this.focusedState = computed(() => Boolean(this.fieldRootContext?.focusedState()), /* @ts-ignore */
|
|
1515
|
+
...(ngDevMode ? [{ debugName: "focusedState" }] : /* istanbul ignore next */ []));
|
|
1032
1516
|
this.describedBy = computed(() => {
|
|
1033
1517
|
if (!this.fieldRootContext) {
|
|
1034
1518
|
return undefined;
|
|
@@ -1038,7 +1522,8 @@ class RdxSelectTrigger {
|
|
|
1038
1522
|
...(this.fieldRootContext.invalidState() ? this.fieldRootContext.errorIds() : [])
|
|
1039
1523
|
];
|
|
1040
1524
|
return ids.length ? ids.join(' ') : undefined;
|
|
1041
|
-
},
|
|
1525
|
+
}, /* @ts-ignore */
|
|
1526
|
+
...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));
|
|
1042
1527
|
this.dataAttr = attr;
|
|
1043
1528
|
afterNextRender(() => {
|
|
1044
1529
|
this.rootContext.onTriggerChange(this.elementRef);
|
|
@@ -1113,10 +1598,10 @@ class RdxSelectTrigger {
|
|
|
1113
1598
|
this.fieldRootContext?.setFocused(false);
|
|
1114
1599
|
this.fieldRootContext?.setTouched(true);
|
|
1115
1600
|
}
|
|
1116
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1117
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "
|
|
1601
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1602
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: RdxSelectTrigger, isStandalone: true, selector: "button[rdxSelectTrigger]", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "combobox", "type": "button" }, listeners: { "click": "onClickHandler($event)", "pointerdown": "onPointerDown($event)", "pointerup": "onPointerUp($event)", "keydown": "onKeydown($event)", "focus": "onFocus()", "blur": "onBlur()" }, properties: { "attr.id": "id()", "attr.aria-describedby": "describedBy()", "attr.aria-controls": "triggerInteraction.ariaControls()", "attr.aria-invalid": "invalidState() ? \"true\" : undefined", "attr.aria-required": "requiredState() ? \"true\" : undefined", "attr.aria-readonly": "readOnlyState() ? \"true\" : undefined", "attr.disabled": "isDisabled() ? \"\" : undefined", "dir": "rootContext.dir()", "attr.data-popup-open": "triggerInteraction.dataPopupOpen()", "attr.data-placeholder": "dataAttr(rootContext.isEmptyModelValue())", "attr.data-disabled": "dataAttr(isDisabled())", "attr.data-invalid": "dataAttr(invalidState())", "attr.data-valid": "dataAttr(!invalidState())", "attr.data-required": "dataAttr(requiredState())", "attr.data-readonly": "dataAttr(readOnlyState())", "attr.data-filled": "dataAttr(filledState())", "attr.data-focused": "dataAttr(focusedState())" } }, hostDirectives: [{ directive: i1.RdxPopperAnchor }], ngImport: i0 }); }
|
|
1118
1603
|
}
|
|
1119
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1604
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectTrigger, decorators: [{
|
|
1120
1605
|
type: Directive,
|
|
1121
1606
|
args: [{
|
|
1122
1607
|
selector: 'button[rdxSelectTrigger]',
|
|
@@ -1129,15 +1614,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
1129
1614
|
'[attr.aria-controls]': 'triggerInteraction.ariaControls()',
|
|
1130
1615
|
'[attr.aria-invalid]': 'invalidState() ? "true" : undefined',
|
|
1131
1616
|
'[attr.aria-required]': 'requiredState() ? "true" : undefined',
|
|
1617
|
+
'[attr.aria-readonly]': 'readOnlyState() ? "true" : undefined',
|
|
1132
1618
|
'[attr.disabled]': 'isDisabled() ? "" : undefined',
|
|
1133
1619
|
'[dir]': 'rootContext.dir()',
|
|
1134
|
-
'[attr.data-state]': 'triggerInteraction.dataState()',
|
|
1135
1620
|
'[attr.data-popup-open]': 'triggerInteraction.dataPopupOpen()',
|
|
1136
1621
|
'[attr.data-placeholder]': 'dataAttr(rootContext.isEmptyModelValue())',
|
|
1137
1622
|
'[attr.data-disabled]': 'dataAttr(isDisabled())',
|
|
1138
1623
|
'[attr.data-invalid]': 'dataAttr(invalidState())',
|
|
1139
1624
|
'[attr.data-valid]': 'dataAttr(!invalidState())',
|
|
1140
1625
|
'[attr.data-required]': 'dataAttr(requiredState())',
|
|
1626
|
+
'[attr.data-readonly]': 'dataAttr(readOnlyState())',
|
|
1141
1627
|
'[attr.data-filled]': 'dataAttr(filledState())',
|
|
1142
1628
|
'[attr.data-focused]': 'dataAttr(focusedState())',
|
|
1143
1629
|
'(click)': 'onClickHandler($event)',
|
|
@@ -1154,10 +1640,12 @@ class RdxSelectValue {
|
|
|
1154
1640
|
constructor() {
|
|
1155
1641
|
this.rootContext = injectSelectRootContext();
|
|
1156
1642
|
this.elementRef = inject(ElementRef);
|
|
1157
|
-
this.placeholder = input(
|
|
1643
|
+
this.placeholder = input(/* @ts-ignore */
|
|
1644
|
+
...(ngDevMode ? [undefined, { debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
1158
1645
|
this.slotText = computed(() => {
|
|
1159
1646
|
return this.selectedLabel().length ? this.selectedLabel().join(', ') : this.placeholder();
|
|
1160
|
-
},
|
|
1647
|
+
}, /* @ts-ignore */
|
|
1648
|
+
...(ngDevMode ? [{ debugName: "slotText" }] : /* istanbul ignore next */ []));
|
|
1161
1649
|
this.selectedLabel = computed(() => {
|
|
1162
1650
|
const options = Array.from(this.rootContext.optionsSet());
|
|
1163
1651
|
const customLabel = this.rootContext.itemToStringLabel();
|
|
@@ -1171,15 +1659,16 @@ class RdxSelectValue {
|
|
|
1171
1659
|
const value = this.rootContext.value();
|
|
1172
1660
|
const list = Array.isArray(value) ? value.map((v) => labelFor(v)) : [labelFor(value)];
|
|
1173
1661
|
return list.filter(Boolean);
|
|
1174
|
-
},
|
|
1662
|
+
}, /* @ts-ignore */
|
|
1663
|
+
...(ngDevMode ? [{ debugName: "selectedLabel" }] : /* istanbul ignore next */ []));
|
|
1175
1664
|
afterNextRender(() => {
|
|
1176
1665
|
this.rootContext.valueElement.set(this.elementRef.nativeElement);
|
|
1177
1666
|
});
|
|
1178
1667
|
}
|
|
1179
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1180
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "
|
|
1668
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectValue, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1669
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: RdxSelectValue, isStandalone: true, selector: "span[rdxSelectValue]", inputs: { placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.pointer-events": "\"none\"" } }, exportAs: ["rdxSelectedValue"], ngImport: i0 }); }
|
|
1181
1670
|
}
|
|
1182
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
1671
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSelectValue, decorators: [{
|
|
1183
1672
|
type: Directive,
|
|
1184
1673
|
args: [{
|
|
1185
1674
|
selector: 'span[rdxSelectValue]',
|
|
@@ -1204,6 +1693,10 @@ const _importsSelect = [
|
|
|
1204
1693
|
RdxSelectGroupLabel,
|
|
1205
1694
|
RdxSelectGroup,
|
|
1206
1695
|
RdxSelectPositioner,
|
|
1696
|
+
RdxSelectItemAlignedPosition,
|
|
1697
|
+
RdxSelectItemAlignedPositionContent,
|
|
1698
|
+
RdxSelectScrollUpButton,
|
|
1699
|
+
RdxSelectScrollDownButton,
|
|
1207
1700
|
RdxSelectIcon,
|
|
1208
1701
|
RdxSelectSeparator,
|
|
1209
1702
|
RdxSelectBackdrop
|
|
@@ -1213,5 +1706,5 @@ const _importsSelect = [
|
|
|
1213
1706
|
* Generated bundle index. Do not edit.
|
|
1214
1707
|
*/
|
|
1215
1708
|
|
|
1216
|
-
export { CONTENT_MARGIN, OPEN_KEYS, RDX_SELECT_POSITIONER_TOKEN, RdxSelectBackdrop, RdxSelectGroup, RdxSelectGroupLabel, RdxSelectIcon, RdxSelectItem, RdxSelectItemIndicator, RdxSelectItemText, RdxSelectList, RdxSelectPopup, RdxSelectPortal, RdxSelectPortalMisuseGuard, RdxSelectPositioner, RdxSelectRoot, RdxSelectSeparator, RdxSelectTrigger, RdxSelectValue, SELECTION_KEYS, _importsSelect, compare, focusFirst, injectSelectItemContext, injectSelectPopupContext, injectSelectRootContext, provideSelectItemContext, provideSelectPopupContext, provideSelectRootContext, shouldShowPlaceholder, valueComparator };
|
|
1709
|
+
export { CONTENT_MARGIN, OPEN_KEYS, RDX_SELECT_POSITIONER_TOKEN, RdxSelectBackdrop, RdxSelectGroup, RdxSelectGroupLabel, RdxSelectIcon, RdxSelectItem, RdxSelectItemAlignedPosition, RdxSelectItemAlignedPositionContent, RdxSelectItemIndicator, RdxSelectItemText, RdxSelectList, RdxSelectPopup, RdxSelectPortal, RdxSelectPortalMisuseGuard, RdxSelectPositioner, RdxSelectRoot, RdxSelectScrollButtonBase, RdxSelectScrollDownButton, RdxSelectScrollUpButton, RdxSelectSeparator, RdxSelectTrigger, RdxSelectValue, SELECTION_KEYS, _importsSelect, compare, focusFirst, injectSelectItemContext, injectSelectPopupContext, injectSelectRootContext, provideSelectItemContext, provideSelectPopupContext, provideSelectRootContext, shouldShowPlaceholder, valueComparator };
|
|
1217
1710
|
//# sourceMappingURL=radix-ng-primitives-select.mjs.map
|