@radix-ng/primitives 1.0.10 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -5
- package/fesm2022/radix-ng-primitives-autocomplete.mjs +24 -16
- package/fesm2022/radix-ng-primitives-autocomplete.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-checkbox.mjs +55 -7
- package/fesm2022/radix-ng-primitives-checkbox.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-combobox.mjs +35 -18
- package/fesm2022/radix-ng-primitives-combobox.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-composite.mjs +221 -36
- package/fesm2022/radix-ng-primitives-composite.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-core.mjs +181 -21
- package/fesm2022/radix-ng-primitives-core.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-date-field.mjs +11 -5
- package/fesm2022/radix-ng-primitives-date-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-field.mjs +127 -23
- package/fesm2022/radix-ng-primitives-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-form.mjs +35 -4
- package/fesm2022/radix-ng-primitives-form.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-input.mjs +87 -15
- package/fesm2022/radix-ng-primitives-input.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-menu.mjs +34 -7
- package/fesm2022/radix-ng-primitives-menu.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-popper.mjs +80 -11
- package/fesm2022/radix-ng-primitives-popper.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-scroll-area.mjs +6 -3
- package/fesm2022/radix-ng-primitives-scroll-area.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-select.mjs +36 -12
- package/fesm2022/radix-ng-primitives-select.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-signal-forms.mjs +27 -11
- package/fesm2022/radix-ng-primitives-signal-forms.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-time-field.mjs +12 -6
- package/fesm2022/radix-ng-primitives-time-field.mjs.map +1 -1
- package/package.json +8 -3
- package/types/radix-ng-primitives-autocomplete.d.ts +7 -2
- package/types/radix-ng-primitives-checkbox.d.ts +10 -1
- package/types/radix-ng-primitives-combobox.d.ts +29 -2
- package/types/radix-ng-primitives-composite.d.ts +48 -2
- package/types/radix-ng-primitives-core.d.ts +152 -94
- package/types/radix-ng-primitives-date-field.d.ts +7 -4
- package/types/radix-ng-primitives-field.d.ts +55 -8
- package/types/radix-ng-primitives-form.d.ts +9 -0
- package/types/radix-ng-primitives-input.d.ts +10 -2
- package/types/radix-ng-primitives-menu.d.ts +45 -4
- package/types/radix-ng-primitives-navigation-menu.d.ts +2 -2
- package/types/radix-ng-primitives-popover.d.ts +2 -2
- package/types/radix-ng-primitives-popper.d.ts +60 -15
- package/types/radix-ng-primitives-preview-card.d.ts +2 -2
- package/types/radix-ng-primitives-select.d.ts +17 -3
- package/types/radix-ng-primitives-signal-forms.d.ts +22 -8
- package/types/radix-ng-primitives-time-field.d.ts +9 -6
- package/types/radix-ng-primitives-tooltip.d.ts +2 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { inject, ElementRef, signal, input, model, booleanAttribute, output, computed, effect, afterNextRender, Directive } from '@angular/core';
|
|
3
|
+
import { injectNgControlState } from '@radix-ng/primitives/core';
|
|
3
4
|
import { injectFieldRootContext } from '@radix-ng/primitives/field';
|
|
4
5
|
|
|
5
6
|
let inputId = 0;
|
|
@@ -15,6 +16,7 @@ class RdxInputDirective {
|
|
|
15
16
|
constructor() {
|
|
16
17
|
this.element = inject(ElementRef).nativeElement;
|
|
17
18
|
this.fieldRootContext = injectFieldRootContext(true);
|
|
19
|
+
this.ngControlState = injectNgControlState();
|
|
18
20
|
this.initialValue = '';
|
|
19
21
|
this.defaultValueApplied = false;
|
|
20
22
|
this.filledValue = signal(false, /* @ts-ignore */
|
|
@@ -76,6 +78,8 @@ class RdxInputDirective {
|
|
|
76
78
|
* @group Props
|
|
77
79
|
*/
|
|
78
80
|
this.invalid = input(false, { ...(ngDevMode ? { debugName: "invalid" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
81
|
+
/** Whether async validation is pending. Pending inputs publish neither valid nor invalid state. */
|
|
82
|
+
this.pending = input(false, { ...(ngDevMode ? { debugName: "pending" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
79
83
|
/**
|
|
80
84
|
* Whether the input has been touched. A two-way model: the input sets it on
|
|
81
85
|
* blur (emitting `touchedChange`, which Signal Forms' `[formField]` listens
|
|
@@ -134,17 +138,44 @@ class RdxInputDirective {
|
|
|
134
138
|
* @group Emits
|
|
135
139
|
*/
|
|
136
140
|
this.touch = output();
|
|
137
|
-
/**
|
|
138
|
-
this.
|
|
141
|
+
/** Validation errors from the input and a same-host Reactive/template-driven form control. */
|
|
142
|
+
this.validationErrors = computed(() => {
|
|
143
|
+
const ownErrors = this.errors() ?? [];
|
|
144
|
+
const ngControlErrors = this.ngControlState.connected() ? this.ngControlState.errors() : [];
|
|
145
|
+
return ngControlErrors.length > 0 ? [...ownErrors, ...ngControlErrors] : ownErrors;
|
|
146
|
+
}, /* @ts-ignore */
|
|
147
|
+
...(ngDevMode ? [{ debugName: "validationErrors" }] : /* istanbul ignore next */ []));
|
|
148
|
+
/** The input's binary invalidity, including a same-host Reactive/template-driven form control. */
|
|
149
|
+
this.ownInvalid = computed(() => this.invalid() ||
|
|
150
|
+
this.validationErrors().length > 0 ||
|
|
151
|
+
Boolean(this.ngControlState.connected() && this.ngControlState.invalid()), /* @ts-ignore */
|
|
139
152
|
...(ngDevMode ? [{ debugName: "ownInvalid" }] : /* istanbul ignore next */ []));
|
|
153
|
+
this.pendingState = computed(() => this.pending() || Boolean(this.ngControlState.connected() && this.ngControlState.pending()), /* @ts-ignore */
|
|
154
|
+
...(ngDevMode ? [{ debugName: "pendingState" }] : /* istanbul ignore next */ []));
|
|
140
155
|
/**
|
|
141
156
|
* Tri-state *displayed* validity: inside a `rdxFieldRoot` the field's gated `validState` is the single
|
|
142
157
|
* source (so a field whose `validationMode` defers display (e.g. `onBlur`) keeps the input neutral until revealed), otherwise
|
|
143
158
|
* the input's own binary invalidity. `true` valid / `false` invalid / `null` neutral.
|
|
144
159
|
*/
|
|
145
|
-
this.displayValid = computed(() =>
|
|
160
|
+
this.displayValid = computed(() => {
|
|
161
|
+
if (this.fieldRootContext) {
|
|
162
|
+
return this.fieldRootContext.validState();
|
|
163
|
+
}
|
|
164
|
+
if (this.pendingState()) {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
if (this.ownInvalid()) {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
if (this.ngControlState.connected() && this.ngControlState.disabled()) {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
return true;
|
|
174
|
+
}, /* @ts-ignore */
|
|
146
175
|
...(ngDevMode ? [{ debugName: "displayValid" }] : /* istanbul ignore next */ []));
|
|
147
|
-
this.disabledState = computed(() => this.disabled() ||
|
|
176
|
+
this.disabledState = computed(() => this.disabled() ||
|
|
177
|
+
Boolean(this.ngControlState.connected() && this.ngControlState.disabled()) ||
|
|
178
|
+
Boolean(this.fieldRootContext?.disabledState()), /* @ts-ignore */
|
|
148
179
|
...(ngDevMode ? [{ debugName: "disabledState" }] : /* istanbul ignore next */ []));
|
|
149
180
|
this.requiredState = computed(() => this.required() || Boolean(this.fieldRootContext?.requiredState()), /* @ts-ignore */
|
|
150
181
|
...(ngDevMode ? [{ debugName: "requiredState" }] : /* istanbul ignore next */ []));
|
|
@@ -152,9 +183,11 @@ class RdxInputDirective {
|
|
|
152
183
|
...(ngDevMode ? [{ debugName: "filledState" }] : /* istanbul ignore next */ []));
|
|
153
184
|
this.focusedState = computed(() => this.focusedValue() || Boolean(this.fieldRootContext?.focusedState()), /* @ts-ignore */
|
|
154
185
|
...(ngDevMode ? [{ debugName: "focusedState" }] : /* istanbul ignore next */ []));
|
|
155
|
-
this.touchedState = computed(() => this.touched()
|
|
186
|
+
this.touchedState = computed(() => (this.ngControlState.connected() ? this.ngControlState.touched() : this.touched()) ||
|
|
187
|
+
Boolean(this.fieldRootContext?.touchedState()), /* @ts-ignore */
|
|
156
188
|
...(ngDevMode ? [{ debugName: "touchedState" }] : /* istanbul ignore next */ []));
|
|
157
|
-
this.dirtyState = computed(() => this.dirty()
|
|
189
|
+
this.dirtyState = computed(() => (this.ngControlState.connected() ? this.ngControlState.dirty() : this.dirty() || this.dirtyValue()) ||
|
|
190
|
+
Boolean(this.fieldRootContext?.dirtyState()), /* @ts-ignore */
|
|
158
191
|
...(ngDevMode ? [{ debugName: "dirtyState" }] : /* istanbul ignore next */ []));
|
|
159
192
|
this.patternAttr = computed(() => {
|
|
160
193
|
const patterns = this.pattern();
|
|
@@ -165,17 +198,14 @@ class RdxInputDirective {
|
|
|
165
198
|
if (!this.fieldRootContext) {
|
|
166
199
|
return undefined;
|
|
167
200
|
}
|
|
168
|
-
const ids = [
|
|
169
|
-
...this.fieldRootContext.descriptionIds(),
|
|
170
|
-
...(this.fieldRootContext.invalidState() ? this.fieldRootContext.errorIds() : [])
|
|
171
|
-
];
|
|
201
|
+
const ids = [...this.fieldRootContext.descriptionIds(), ...this.fieldRootContext.errorIds()];
|
|
172
202
|
return ids.length ? ids.join(' ') : undefined;
|
|
173
203
|
}, /* @ts-ignore */
|
|
174
204
|
...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));
|
|
175
205
|
this.dataAttr = attr;
|
|
176
206
|
effect(() => {
|
|
177
207
|
const value = this.value();
|
|
178
|
-
if (value !== undefined) {
|
|
208
|
+
if (!this.ngControlState.connected() && value !== undefined) {
|
|
179
209
|
this.writeValue(value);
|
|
180
210
|
}
|
|
181
211
|
});
|
|
@@ -189,6 +219,29 @@ class RdxInputDirective {
|
|
|
189
219
|
effect(() => {
|
|
190
220
|
this.fieldRootContext?.setControlId(this.id());
|
|
191
221
|
});
|
|
222
|
+
// Reactive/template-driven forms own their NgControl interaction state. Keep the enclosing
|
|
223
|
+
// Field in sync too, including programmatic markAsPristine/markAsUntouched transitions.
|
|
224
|
+
effect(() => {
|
|
225
|
+
if (this.ngControlState.connected()) {
|
|
226
|
+
// Angular's DefaultValueAccessor has already written the latest form-owned value to
|
|
227
|
+
// the native element before `AbstractControl.events` emits. Mirror that DOM string
|
|
228
|
+
// into the directive model without letting its standalone value effect write back.
|
|
229
|
+
this.ngControlState.value();
|
|
230
|
+
const touched = this.ngControlState.touched();
|
|
231
|
+
const dirty = this.ngControlState.dirty();
|
|
232
|
+
this.value.set(this.element.value);
|
|
233
|
+
this.touched.set(touched);
|
|
234
|
+
this.dirtyValue.set(dirty);
|
|
235
|
+
this.fieldRootContext?.setTouched(touched);
|
|
236
|
+
this.fieldRootContext?.setDirty(dirty);
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
// Signal Forms writes `dirty=false` when resetting the field. A standalone input's dirty
|
|
240
|
+
// input stays false and does not re-run this effect after ordinary user edits.
|
|
241
|
+
if (!this.dirty()) {
|
|
242
|
+
this.dirtyValue.set(false);
|
|
243
|
+
}
|
|
244
|
+
}, { debugName: 'RdxInput.syncInteractionState' });
|
|
192
245
|
afterNextRender(() => {
|
|
193
246
|
this.initialValue = this.element.value;
|
|
194
247
|
this.syncFieldState();
|
|
@@ -223,19 +276,38 @@ class RdxInputDirective {
|
|
|
223
276
|
this.value.set(nextValue);
|
|
224
277
|
this.syncFieldState();
|
|
225
278
|
}
|
|
279
|
+
/** Reset the interaction baseline; Angular Signal Forms calls this from `FieldState.reset()`. */
|
|
280
|
+
reset() {
|
|
281
|
+
this.touched.set(false);
|
|
282
|
+
this.dirtyValue.set(false);
|
|
283
|
+
this.focusedValue.set(false);
|
|
284
|
+
this.fieldRootContext?.setTouched(false);
|
|
285
|
+
this.fieldRootContext?.setDirty(false);
|
|
286
|
+
this.fieldRootContext?.setFocused(false);
|
|
287
|
+
// The form writes the reset value through `value` after invoking this hook. Capture that final
|
|
288
|
+
// rendered value as the next dirty baseline, rather than the value that happened to be present
|
|
289
|
+
// when reset started.
|
|
290
|
+
queueMicrotask(() => {
|
|
291
|
+
this.initialValue = this.element.value;
|
|
292
|
+
this.dirtyValue.set(false);
|
|
293
|
+
this.fieldRootContext?.setDirty(false);
|
|
294
|
+
this.syncFieldState();
|
|
295
|
+
});
|
|
296
|
+
}
|
|
226
297
|
syncFieldState() {
|
|
227
298
|
const value = this.element.value;
|
|
299
|
+
const dirty = this.ngControlState.connected() ? this.ngControlState.dirty() : value !== this.initialValue;
|
|
228
300
|
this.filledValue.set(value !== '');
|
|
229
|
-
this.dirtyValue.set(
|
|
301
|
+
this.dirtyValue.set(dirty);
|
|
230
302
|
this.fieldRootContext?.setFilled(value !== '');
|
|
231
|
-
this.fieldRootContext?.setDirty(
|
|
303
|
+
this.fieldRootContext?.setDirty(dirty);
|
|
232
304
|
}
|
|
233
305
|
writeValue(value) {
|
|
234
306
|
this.element.value = value;
|
|
235
307
|
this.syncFieldState();
|
|
236
308
|
}
|
|
237
309
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxInputDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
238
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: RdxInputDirective, isStandalone: true, selector: "input[rdxInput]", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", 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 }, 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 }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, dirty: { classPropertyName: "dirty", publicName: "dirty", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, minLength: { classPropertyName: "minLength", publicName: "minLength", isSignal: true, isRequired: false, transformFunction: null }, maxLength: { classPropertyName: "maxLength", publicName: "maxLength", isSignal: true, isRequired: false, transformFunction: null }, pattern: { classPropertyName: "pattern", publicName: "pattern", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touched: "touchedChange", onValueChange: "onValueChange", touch: "touch" }, host: { listeners: { "focus": "onFocus()", "blur": "onBlur()", "input": "onInput($event)", "change": "syncFieldState()" }, properties: { "attr.id": "id()", "attr.name": "name() || undefined", "attr.aria-describedby": "describedBy()", "attr.aria-invalid": "displayValid() === false ? \"true\" : undefined", "attr.aria-required": "requiredState() ? \"true\" : undefined", "attr.aria-disabled": "disabledState() ? \"true\" : undefined", "attr.disabled": "disabledState() ? \"\" : undefined", "attr.required": "requiredState() ? \"\" : undefined", "attr.readonly": "readonly() ? \"\" : undefined", "attr.minlength": "minLength() ?? undefined", "attr.maxlength": "maxLength() ?? undefined", "attr.pattern": "patternAttr()", "attr.data-invalid": "dataAttr(displayValid() === false)", "attr.data-valid": "dataAttr(displayValid() === true)", "attr.data-disabled": "dataAttr(disabledState())", "attr.data-required": "dataAttr(requiredState())", "attr.data-readonly": "dataAttr(readonly())", "attr.data-filled": "dataAttr(filledState())", "attr.data-focused": "dataAttr(focusedState())", "attr.data-touched": "dataAttr(touchedState())", "attr.data-dirty": "dataAttr(dirtyState())" } }, exportAs: ["rdxInput"], ngImport: i0 }); }
|
|
310
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: RdxInputDirective, isStandalone: true, selector: "input[rdxInput]", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", 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 }, 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 }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, pending: { classPropertyName: "pending", publicName: "pending", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, dirty: { classPropertyName: "dirty", publicName: "dirty", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, minLength: { classPropertyName: "minLength", publicName: "minLength", isSignal: true, isRequired: false, transformFunction: null }, maxLength: { classPropertyName: "maxLength", publicName: "maxLength", isSignal: true, isRequired: false, transformFunction: null }, pattern: { classPropertyName: "pattern", publicName: "pattern", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touched: "touchedChange", onValueChange: "onValueChange", touch: "touch" }, host: { listeners: { "focus": "onFocus()", "blur": "onBlur()", "input": "onInput($event)", "change": "syncFieldState()" }, properties: { "attr.id": "id()", "attr.name": "name() || undefined", "attr.aria-describedby": "describedBy()", "attr.aria-invalid": "displayValid() === false ? \"true\" : undefined", "attr.aria-required": "requiredState() ? \"true\" : undefined", "attr.aria-disabled": "disabledState() ? \"true\" : undefined", "attr.disabled": "disabledState() ? \"\" : undefined", "attr.required": "requiredState() ? \"\" : undefined", "attr.readonly": "readonly() ? \"\" : undefined", "attr.minlength": "minLength() ?? undefined", "attr.maxlength": "maxLength() ?? undefined", "attr.pattern": "patternAttr()", "attr.data-invalid": "dataAttr(displayValid() === false)", "attr.data-valid": "dataAttr(displayValid() === true)", "attr.data-disabled": "dataAttr(disabledState())", "attr.data-required": "dataAttr(requiredState())", "attr.data-readonly": "dataAttr(readonly())", "attr.data-filled": "dataAttr(filledState())", "attr.data-focused": "dataAttr(focusedState())", "attr.data-touched": "dataAttr(touchedState())", "attr.data-dirty": "dataAttr(dirtyState())" } }, exportAs: ["rdxInput"], ngImport: i0 }); }
|
|
239
311
|
}
|
|
240
312
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxInputDirective, decorators: [{
|
|
241
313
|
type: Directive,
|
|
@@ -272,7 +344,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImpor
|
|
|
272
344
|
'(change)': 'syncFieldState()'
|
|
273
345
|
}
|
|
274
346
|
}]
|
|
275
|
-
}], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], 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 }] }], 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 }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], dirty: [{ type: i0.Input, args: [{ isSignal: true, alias: "dirty", required: false }] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], minLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "minLength", required: false }] }], maxLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxLength", required: false }] }], pattern: [{ type: i0.Input, args: [{ isSignal: true, alias: "pattern", required: false }] }], onValueChange: [{ type: i0.Output, args: ["onValueChange"] }], touch: [{ type: i0.Output, args: ["touch"] }] } });
|
|
347
|
+
}], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], 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 }] }], 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 }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], pending: [{ type: i0.Input, args: [{ isSignal: true, alias: "pending", required: false }] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], dirty: [{ type: i0.Input, args: [{ isSignal: true, alias: "dirty", required: false }] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], minLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "minLength", required: false }] }], maxLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxLength", required: false }] }], pattern: [{ type: i0.Input, args: [{ isSignal: true, alias: "pattern", required: false }] }], onValueChange: [{ type: i0.Output, args: ["onValueChange"] }], touch: [{ type: i0.Output, args: ["touch"] }] } });
|
|
276
348
|
|
|
277
349
|
/**
|
|
278
350
|
* Generated bundle index. Do not edit.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"radix-ng-primitives-input.mjs","sources":["../../../packages/primitives/input/src/input.directive.ts","../../../packages/primitives/input/radix-ng-primitives-input.ts"],"sourcesContent":["import {\n afterNextRender,\n booleanAttribute,\n computed,\n Directive,\n effect,\n ElementRef,\n inject,\n input,\n model,\n output,\n signal\n} from '@angular/core';\nimport { BooleanInput, NumberInput, RdxFormValueControl, RdxValidationError } from '@radix-ng/primitives/core';\nimport { injectFieldRootContext } from '@radix-ng/primitives/field';\n\nlet inputId = 0;\n\nconst attr = (value: boolean) => (value ? '' : undefined);\nconst numberOrUndefined = (value: unknown): number | undefined =>\n value == null || value === '' ? undefined : Number(value);\n\n/**\n * The input value. Native text inputs always produce strings, so the model is\n * `string` — matching Signal Forms' `FormValueControl<string>` round-trip.\n */\nexport type RdxInputValue = string;\n\nexport interface RdxInputValueChangeEventDetails {\n event: Event;\n cancel: () => void;\n isCanceled: () => boolean;\n}\n\nexport interface RdxInputValueChangeEvent {\n value: string;\n eventDetails: RdxInputValueChangeEventDetails;\n}\n\n/**\n * A headless text input that can integrate with Field for accessible labeling,\n * descriptions, validation state, and data attributes.\n *\n * @group Components\n */\n@Directive({\n selector: 'input[rdxInput]',\n exportAs: 'rdxInput',\n host: {\n '[attr.id]': 'id()',\n '[attr.name]': 'name() || undefined',\n '[attr.aria-describedby]': 'describedBy()',\n // Validity follows the field's tri-state `displayValid` when inside a `rdxFieldRoot` (neutral →\n // no aria-invalid, neither data-valid nor data-invalid), else the input's own binary invalidity.\n '[attr.aria-invalid]': 'displayValid() === false ? \"true\" : undefined',\n '[attr.aria-required]': 'requiredState() ? \"true\" : undefined',\n '[attr.aria-disabled]': 'disabledState() ? \"true\" : undefined',\n '[attr.disabled]': 'disabledState() ? \"\" : undefined',\n '[attr.required]': 'requiredState() ? \"\" : undefined',\n '[attr.readonly]': 'readonly() ? \"\" : undefined',\n '[attr.minlength]': 'minLength() ?? undefined',\n '[attr.maxlength]': 'maxLength() ?? undefined',\n '[attr.pattern]': 'patternAttr()',\n '[attr.data-invalid]': 'dataAttr(displayValid() === false)',\n '[attr.data-valid]': 'dataAttr(displayValid() === true)',\n '[attr.data-disabled]': 'dataAttr(disabledState())',\n '[attr.data-required]': 'dataAttr(requiredState())',\n '[attr.data-readonly]': 'dataAttr(readonly())',\n '[attr.data-filled]': 'dataAttr(filledState())',\n '[attr.data-focused]': 'dataAttr(focusedState())',\n '[attr.data-touched]': 'dataAttr(touchedState())',\n '[attr.data-dirty]': 'dataAttr(dirtyState())',\n '(focus)': 'onFocus()',\n '(blur)': 'onBlur()',\n '(input)': 'onInput($event)',\n '(change)': 'syncFieldState()'\n }\n})\nexport class RdxInputDirective implements RdxFormValueControl<RdxInputValue | undefined> {\n private readonly element = inject<ElementRef<HTMLInputElement>>(ElementRef).nativeElement;\n private readonly fieldRootContext = injectFieldRootContext(true);\n private initialValue = '';\n private defaultValueApplied = false;\n private readonly filledValue = signal(false);\n private readonly focusedValue = signal(false);\n private readonly dirtyValue = signal(false);\n\n /**\n * The input id. Field labels and descriptions use this value for accessible relationships.\n *\n * @group Props\n */\n readonly id = input(`rdx-input-${inputId++}`);\n\n /**\n * The name of the input, submitted with the form data and used by Form-level\n * error matching.\n *\n * @group Props\n */\n readonly name = input<string>();\n\n /**\n * The controlled input value.\n *\n * @group Props\n */\n readonly value = model<RdxInputValue | undefined>(undefined);\n\n /**\n * The initial value when the input is uncontrolled.\n *\n * @group Props\n */\n readonly defaultValue = input<RdxInputValue | undefined>(undefined);\n\n /**\n * Whether the input is disabled.\n *\n * @group Props\n */\n readonly disabled = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /**\n * Whether the input is read-only.\n *\n * @group Props\n */\n readonly readonly = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /**\n * Whether the input is required.\n *\n * @group Props\n */\n readonly required = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /**\n * Whether the input is invalid.\n *\n * @group Props\n */\n readonly invalid = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /**\n * Whether the input has been touched. A two-way model: the input sets it on\n * blur (emitting `touchedChange`, which Signal Forms' `[formField]` listens\n * to), and a form system can write it back.\n *\n * @group Props\n */\n readonly touched = model<boolean>(false);\n\n /**\n * Whether the input value has changed from its initial value. Merged with the\n * internally tracked state; a form system can own it through this input.\n *\n * @group Props\n */\n readonly dirty = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /**\n * Validation errors for the input. A non-empty list marks the input invalid.\n *\n * @group Props\n */\n readonly errors = input<readonly RdxValidationError[]>([]);\n\n /**\n * Minimum number of characters.\n *\n * @group Props\n */\n readonly minLength = input<number | undefined, NumberInput>(undefined, { transform: numberOrUndefined });\n\n /**\n * Maximum number of characters.\n *\n * @group Props\n */\n readonly maxLength = input<number | undefined, NumberInput>(undefined, { transform: numberOrUndefined });\n\n /**\n * Patterns the value must match. Reflected to the native `pattern` attribute\n * only when exactly one pattern is provided (the attribute holds a single regex).\n *\n * @group Props\n */\n readonly pattern = input<readonly RegExp[]>([]);\n\n /**\n * Emits when the input value changes.\n *\n * @group Emits\n */\n readonly onValueChange = output<RdxInputValueChangeEvent>();\n\n /**\n * Emits on blur, notifying a form system the input was touched. Stable\n * Angular 22 Signal Forms listens to this `touch` output; the 21.x\n * experimental implementation listens to the `touched` model's\n * `touchedChange` instead — both are emitted, covering either version.\n *\n * @group Emits\n */\n readonly touch = output<void>();\n\n /** The input's own binary invalidity (its `invalid` input or a non-empty `errors` list). */\n private readonly ownInvalid = computed(() => this.invalid() || (this.errors()?.length ?? 0) > 0);\n\n /**\n * Tri-state *displayed* validity: inside a `rdxFieldRoot` the field's gated `validState` is the single\n * source (so a field whose `validationMode` defers display (e.g. `onBlur`) keeps the input neutral until revealed), otherwise\n * the input's own binary invalidity. `true` valid / `false` invalid / `null` neutral.\n */\n protected readonly displayValid = computed<boolean | null>(() =>\n this.fieldRootContext ? this.fieldRootContext.validState() : this.ownInvalid() ? false : true\n );\n protected readonly disabledState = computed(\n () => this.disabled() || Boolean(this.fieldRootContext?.disabledState())\n );\n protected readonly requiredState = computed(\n () => this.required() || Boolean(this.fieldRootContext?.requiredState())\n );\n protected readonly filledState = computed(\n () => this.filledValue() || Boolean(this.fieldRootContext?.filledState())\n );\n protected readonly focusedState = computed(\n () => this.focusedValue() || Boolean(this.fieldRootContext?.focusedState())\n );\n protected readonly touchedState = computed(() => this.touched() || Boolean(this.fieldRootContext?.touchedState()));\n protected readonly dirtyState = computed(\n () => this.dirty() || this.dirtyValue() || Boolean(this.fieldRootContext?.dirtyState())\n );\n\n protected readonly patternAttr = computed(() => {\n const patterns = this.pattern();\n return patterns?.length === 1 ? patterns[0].source : undefined;\n });\n\n protected readonly describedBy = computed(() => {\n if (!this.fieldRootContext) {\n return undefined;\n }\n\n const ids = [\n ...this.fieldRootContext.descriptionIds(),\n ...(this.fieldRootContext.invalidState() ? this.fieldRootContext.errorIds() : [])\n ];\n\n return ids.length ? ids.join(' ') : undefined;\n });\n\n constructor() {\n effect(() => {\n const value = this.value();\n\n if (value !== undefined) {\n this.writeValue(value);\n }\n });\n\n effect(() => {\n const defaultValue = this.defaultValue();\n\n if (this.value() === undefined && defaultValue !== undefined && !this.defaultValueApplied) {\n this.defaultValueApplied = true;\n this.writeValue(defaultValue);\n }\n });\n\n effect(() => {\n this.fieldRootContext?.setControlId(this.id());\n });\n\n afterNextRender(() => {\n this.initialValue = this.element.value;\n this.syncFieldState();\n });\n }\n\n onFocus(): void {\n this.focusedValue.set(true);\n this.fieldRootContext?.setFocused(true);\n }\n\n onBlur(): void {\n this.focusedValue.set(false);\n this.touched.set(true);\n this.touch.emit();\n this.fieldRootContext?.setFocused(false);\n this.fieldRootContext?.setTouched(true);\n }\n\n onInput(event: Event): void {\n const nextValue = this.element.value;\n let canceled = false;\n\n const eventDetails: RdxInputValueChangeEventDetails = {\n event,\n cancel: () => {\n canceled = true;\n },\n isCanceled: () => canceled\n };\n\n this.onValueChange.emit({ value: nextValue, eventDetails });\n\n if (canceled) {\n this.writeValue(this.value() ?? this.defaultValue() ?? '');\n return;\n }\n\n this.value.set(nextValue);\n this.syncFieldState();\n }\n\n syncFieldState(): void {\n const value = this.element.value;\n\n this.filledValue.set(value !== '');\n this.dirtyValue.set(value !== this.initialValue);\n this.fieldRootContext?.setFilled(value !== '');\n this.fieldRootContext?.setDirty(value !== this.initialValue);\n }\n\n private writeValue(value: RdxInputValue): void {\n this.element.value = value;\n this.syncFieldState();\n }\n\n protected readonly dataAttr = attr;\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"radix-ng-primitives-input.mjs","sources":["../../../packages/primitives/input/src/input.directive.ts","../../../packages/primitives/input/radix-ng-primitives-input.ts"],"sourcesContent":["import {\n afterNextRender,\n booleanAttribute,\n computed,\n Directive,\n effect,\n ElementRef,\n inject,\n input,\n model,\n output,\n signal\n} from '@angular/core';\nimport {\n BooleanInput,\n injectNgControlState,\n NumberInput,\n RdxFormValueControl,\n RdxValidationError\n} from '@radix-ng/primitives/core';\nimport { injectFieldRootContext } from '@radix-ng/primitives/field';\n\nlet inputId = 0;\n\nconst attr = (value: boolean) => (value ? '' : undefined);\nconst numberOrUndefined = (value: unknown): number | undefined =>\n value == null || value === '' ? undefined : Number(value);\n\n/**\n * The input value. Native text inputs always produce strings, so the model is\n * `string` — matching Signal Forms' `FormValueControl<string>` round-trip.\n */\nexport type RdxInputValue = string;\n\nexport interface RdxInputValueChangeEventDetails {\n event: Event;\n cancel: () => void;\n isCanceled: () => boolean;\n}\n\nexport interface RdxInputValueChangeEvent {\n value: string;\n eventDetails: RdxInputValueChangeEventDetails;\n}\n\n/**\n * A headless text input that can integrate with Field for accessible labeling,\n * descriptions, validation state, and data attributes.\n *\n * @group Components\n */\n@Directive({\n selector: 'input[rdxInput]',\n exportAs: 'rdxInput',\n host: {\n '[attr.id]': 'id()',\n '[attr.name]': 'name() || undefined',\n '[attr.aria-describedby]': 'describedBy()',\n // Validity follows the field's tri-state `displayValid` when inside a `rdxFieldRoot` (neutral →\n // no aria-invalid, neither data-valid nor data-invalid), else the input's own binary invalidity.\n '[attr.aria-invalid]': 'displayValid() === false ? \"true\" : undefined',\n '[attr.aria-required]': 'requiredState() ? \"true\" : undefined',\n '[attr.aria-disabled]': 'disabledState() ? \"true\" : undefined',\n '[attr.disabled]': 'disabledState() ? \"\" : undefined',\n '[attr.required]': 'requiredState() ? \"\" : undefined',\n '[attr.readonly]': 'readonly() ? \"\" : undefined',\n '[attr.minlength]': 'minLength() ?? undefined',\n '[attr.maxlength]': 'maxLength() ?? undefined',\n '[attr.pattern]': 'patternAttr()',\n '[attr.data-invalid]': 'dataAttr(displayValid() === false)',\n '[attr.data-valid]': 'dataAttr(displayValid() === true)',\n '[attr.data-disabled]': 'dataAttr(disabledState())',\n '[attr.data-required]': 'dataAttr(requiredState())',\n '[attr.data-readonly]': 'dataAttr(readonly())',\n '[attr.data-filled]': 'dataAttr(filledState())',\n '[attr.data-focused]': 'dataAttr(focusedState())',\n '[attr.data-touched]': 'dataAttr(touchedState())',\n '[attr.data-dirty]': 'dataAttr(dirtyState())',\n '(focus)': 'onFocus()',\n '(blur)': 'onBlur()',\n '(input)': 'onInput($event)',\n '(change)': 'syncFieldState()'\n }\n})\nexport class RdxInputDirective implements RdxFormValueControl<RdxInputValue | undefined> {\n private readonly element = inject<ElementRef<HTMLInputElement>>(ElementRef).nativeElement;\n private readonly fieldRootContext = injectFieldRootContext(true);\n private readonly ngControlState = injectNgControlState();\n private initialValue = '';\n private defaultValueApplied = false;\n private readonly filledValue = signal(false);\n private readonly focusedValue = signal(false);\n private readonly dirtyValue = signal(false);\n\n /**\n * The input id. Field labels and descriptions use this value for accessible relationships.\n *\n * @group Props\n */\n readonly id = input(`rdx-input-${inputId++}`);\n\n /**\n * The name of the input, submitted with the form data and used by Form-level\n * error matching.\n *\n * @group Props\n */\n readonly name = input<string>();\n\n /**\n * The controlled input value.\n *\n * @group Props\n */\n readonly value = model<RdxInputValue | undefined>(undefined);\n\n /**\n * The initial value when the input is uncontrolled.\n *\n * @group Props\n */\n readonly defaultValue = input<RdxInputValue | undefined>(undefined);\n\n /**\n * Whether the input is disabled.\n *\n * @group Props\n */\n readonly disabled = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /**\n * Whether the input is read-only.\n *\n * @group Props\n */\n readonly readonly = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /**\n * Whether the input is required.\n *\n * @group Props\n */\n readonly required = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /**\n * Whether the input is invalid.\n *\n * @group Props\n */\n readonly invalid = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /** Whether async validation is pending. Pending inputs publish neither valid nor invalid state. */\n readonly pending = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /**\n * Whether the input has been touched. A two-way model: the input sets it on\n * blur (emitting `touchedChange`, which Signal Forms' `[formField]` listens\n * to), and a form system can write it back.\n *\n * @group Props\n */\n readonly touched = model<boolean>(false);\n\n /**\n * Whether the input value has changed from its initial value. Merged with the\n * internally tracked state; a form system can own it through this input.\n *\n * @group Props\n */\n readonly dirty = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /**\n * Validation errors for the input. A non-empty list marks the input invalid.\n *\n * @group Props\n */\n readonly errors = input<readonly RdxValidationError[]>([]);\n\n /**\n * Minimum number of characters.\n *\n * @group Props\n */\n readonly minLength = input<number | undefined, NumberInput>(undefined, { transform: numberOrUndefined });\n\n /**\n * Maximum number of characters.\n *\n * @group Props\n */\n readonly maxLength = input<number | undefined, NumberInput>(undefined, { transform: numberOrUndefined });\n\n /**\n * Patterns the value must match. Reflected to the native `pattern` attribute\n * only when exactly one pattern is provided (the attribute holds a single regex).\n *\n * @group Props\n */\n readonly pattern = input<readonly RegExp[]>([]);\n\n /**\n * Emits when the input value changes.\n *\n * @group Emits\n */\n readonly onValueChange = output<RdxInputValueChangeEvent>();\n\n /**\n * Emits on blur, notifying a form system the input was touched. Stable\n * Angular 22 Signal Forms listens to this `touch` output; the 21.x\n * experimental implementation listens to the `touched` model's\n * `touchedChange` instead — both are emitted, covering either version.\n *\n * @group Emits\n */\n readonly touch = output<void>();\n\n /** Validation errors from the input and a same-host Reactive/template-driven form control. */\n readonly validationErrors = computed<readonly RdxValidationError[]>(() => {\n const ownErrors = this.errors() ?? [];\n const ngControlErrors = this.ngControlState.connected() ? this.ngControlState.errors() : [];\n return ngControlErrors.length > 0 ? [...ownErrors, ...ngControlErrors] : ownErrors;\n });\n\n /** The input's binary invalidity, including a same-host Reactive/template-driven form control. */\n private readonly ownInvalid = computed(\n () =>\n this.invalid() ||\n this.validationErrors().length > 0 ||\n Boolean(this.ngControlState.connected() && this.ngControlState.invalid())\n );\n private readonly pendingState = computed(\n () => this.pending() || Boolean(this.ngControlState.connected() && this.ngControlState.pending())\n );\n\n /**\n * Tri-state *displayed* validity: inside a `rdxFieldRoot` the field's gated `validState` is the single\n * source (so a field whose `validationMode` defers display (e.g. `onBlur`) keeps the input neutral until revealed), otherwise\n * the input's own binary invalidity. `true` valid / `false` invalid / `null` neutral.\n */\n protected readonly displayValid = computed<boolean | null>(() => {\n if (this.fieldRootContext) {\n return this.fieldRootContext.validState();\n }\n if (this.pendingState()) {\n return null;\n }\n if (this.ownInvalid()) {\n return false;\n }\n if (this.ngControlState.connected() && this.ngControlState.disabled()) {\n return null;\n }\n return true;\n });\n protected readonly disabledState = computed(\n () =>\n this.disabled() ||\n Boolean(this.ngControlState.connected() && this.ngControlState.disabled()) ||\n Boolean(this.fieldRootContext?.disabledState())\n );\n protected readonly requiredState = computed(\n () => this.required() || Boolean(this.fieldRootContext?.requiredState())\n );\n protected readonly filledState = computed(\n () => this.filledValue() || Boolean(this.fieldRootContext?.filledState())\n );\n protected readonly focusedState = computed(\n () => this.focusedValue() || Boolean(this.fieldRootContext?.focusedState())\n );\n protected readonly touchedState = computed(\n () =>\n (this.ngControlState.connected() ? this.ngControlState.touched() : this.touched()) ||\n Boolean(this.fieldRootContext?.touchedState())\n );\n protected readonly dirtyState = computed(\n () =>\n (this.ngControlState.connected() ? this.ngControlState.dirty() : this.dirty() || this.dirtyValue()) ||\n Boolean(this.fieldRootContext?.dirtyState())\n );\n\n protected readonly patternAttr = computed(() => {\n const patterns = this.pattern();\n return patterns?.length === 1 ? patterns[0].source : undefined;\n });\n\n protected readonly describedBy = computed(() => {\n if (!this.fieldRootContext) {\n return undefined;\n }\n\n const ids = [...this.fieldRootContext.descriptionIds(), ...this.fieldRootContext.errorIds()];\n\n return ids.length ? ids.join(' ') : undefined;\n });\n\n constructor() {\n effect(() => {\n const value = this.value();\n\n if (!this.ngControlState.connected() && value !== undefined) {\n this.writeValue(value);\n }\n });\n\n effect(() => {\n const defaultValue = this.defaultValue();\n\n if (this.value() === undefined && defaultValue !== undefined && !this.defaultValueApplied) {\n this.defaultValueApplied = true;\n this.writeValue(defaultValue);\n }\n });\n\n effect(() => {\n this.fieldRootContext?.setControlId(this.id());\n });\n\n // Reactive/template-driven forms own their NgControl interaction state. Keep the enclosing\n // Field in sync too, including programmatic markAsPristine/markAsUntouched transitions.\n effect(\n () => {\n if (this.ngControlState.connected()) {\n // Angular's DefaultValueAccessor has already written the latest form-owned value to\n // the native element before `AbstractControl.events` emits. Mirror that DOM string\n // into the directive model without letting its standalone value effect write back.\n this.ngControlState.value();\n const touched = this.ngControlState.touched();\n const dirty = this.ngControlState.dirty();\n this.value.set(this.element.value);\n this.touched.set(touched);\n this.dirtyValue.set(dirty);\n this.fieldRootContext?.setTouched(touched);\n this.fieldRootContext?.setDirty(dirty);\n return;\n }\n\n // Signal Forms writes `dirty=false` when resetting the field. A standalone input's dirty\n // input stays false and does not re-run this effect after ordinary user edits.\n if (!this.dirty()) {\n this.dirtyValue.set(false);\n }\n },\n { debugName: 'RdxInput.syncInteractionState' }\n );\n\n afterNextRender(() => {\n this.initialValue = this.element.value;\n this.syncFieldState();\n });\n }\n\n onFocus(): void {\n this.focusedValue.set(true);\n this.fieldRootContext?.setFocused(true);\n }\n\n onBlur(): void {\n this.focusedValue.set(false);\n this.touched.set(true);\n this.touch.emit();\n this.fieldRootContext?.setFocused(false);\n this.fieldRootContext?.setTouched(true);\n }\n\n onInput(event: Event): void {\n const nextValue = this.element.value;\n let canceled = false;\n\n const eventDetails: RdxInputValueChangeEventDetails = {\n event,\n cancel: () => {\n canceled = true;\n },\n isCanceled: () => canceled\n };\n\n this.onValueChange.emit({ value: nextValue, eventDetails });\n\n if (canceled) {\n this.writeValue(this.value() ?? this.defaultValue() ?? '');\n return;\n }\n\n this.value.set(nextValue);\n this.syncFieldState();\n }\n\n /** Reset the interaction baseline; Angular Signal Forms calls this from `FieldState.reset()`. */\n reset(): void {\n this.touched.set(false);\n this.dirtyValue.set(false);\n this.focusedValue.set(false);\n this.fieldRootContext?.setTouched(false);\n this.fieldRootContext?.setDirty(false);\n this.fieldRootContext?.setFocused(false);\n\n // The form writes the reset value through `value` after invoking this hook. Capture that final\n // rendered value as the next dirty baseline, rather than the value that happened to be present\n // when reset started.\n queueMicrotask(() => {\n this.initialValue = this.element.value;\n this.dirtyValue.set(false);\n this.fieldRootContext?.setDirty(false);\n this.syncFieldState();\n });\n }\n\n syncFieldState(): void {\n const value = this.element.value;\n const dirty = this.ngControlState.connected() ? this.ngControlState.dirty() : value !== this.initialValue;\n\n this.filledValue.set(value !== '');\n this.dirtyValue.set(dirty);\n this.fieldRootContext?.setFilled(value !== '');\n this.fieldRootContext?.setDirty(dirty);\n }\n\n private writeValue(value: RdxInputValue): void {\n this.element.value = value;\n this.syncFieldState();\n }\n\n protected readonly dataAttr = attr;\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -109,6 +109,7 @@ function buildContext(instance) {
|
|
|
109
109
|
hasTriggerInteractionHandler: instance.hasTriggerInteractionHandler.asReadonly(),
|
|
110
110
|
trigger: instance.trigger.asReadonly(),
|
|
111
111
|
popupElement: instance.popupElement.asReadonly(),
|
|
112
|
+
popupPhysicalSide: instance.popupPhysicalSide,
|
|
112
113
|
beforeContentFocusGuard: instance.beforeContentFocusGuard.asReadonly(),
|
|
113
114
|
transitionStatus: instance.transitionStatus,
|
|
114
115
|
close: (reason, event) => instance.close(reason, event),
|
|
@@ -118,7 +119,7 @@ function buildContext(instance) {
|
|
|
118
119
|
show: (autoFocus, reason, event) => instance.show(autoFocus, reason, event),
|
|
119
120
|
showWithoutAutoFocus: (reason, event) => instance.show(false, reason, event),
|
|
120
121
|
registerTrigger: (el) => instance.registerTrigger(el),
|
|
121
|
-
registerPopup: (el) => instance.registerPopup(el),
|
|
122
|
+
registerPopup: (el, physicalSide) => instance.registerPopup(el, physicalSide),
|
|
122
123
|
setBeforeContentFocusGuard: (element) => instance.setBeforeContentFocusGuard(element),
|
|
123
124
|
registerTransitionElement: (el) => instance.registerTransitionElement(el),
|
|
124
125
|
registerPopupArrowNavigationHandler: (handler) => instance.registerPopupArrowNavigationHandler(handler),
|
|
@@ -185,6 +186,11 @@ class RdxMenuRoot {
|
|
|
185
186
|
...(ngDevMode ? [{ debugName: "trigger" }] : /* istanbul ignore next */ []));
|
|
186
187
|
this.popupElement = signal(undefined, /* @ts-ignore */
|
|
187
188
|
...(ngDevMode ? [{ debugName: "popupElement" }] : /* istanbul ignore next */ []));
|
|
189
|
+
this.popupPhysicalSideSource = signal(undefined, /* @ts-ignore */
|
|
190
|
+
...(ngDevMode ? [{ debugName: "popupPhysicalSideSource" }] : /* istanbul ignore next */ []));
|
|
191
|
+
/** Physical placed side read through the popup's own signal (undefined until the popup is placed). */
|
|
192
|
+
this.popupPhysicalSide = computed(() => this.popupPhysicalSideSource()?.(), /* @ts-ignore */
|
|
193
|
+
...(ngDevMode ? [{ debugName: "popupPhysicalSide" }] : /* istanbul ignore next */ []));
|
|
188
194
|
this.beforeContentFocusGuard = signal(null, /* @ts-ignore */
|
|
189
195
|
...(ngDevMode ? [{ debugName: "beforeContentFocusGuard" }] : /* istanbul ignore next */ []));
|
|
190
196
|
this.transitionStatus = this.transition.status;
|
|
@@ -388,11 +394,13 @@ class RdxMenuRoot {
|
|
|
388
394
|
}
|
|
389
395
|
};
|
|
390
396
|
}
|
|
391
|
-
registerPopup(el) {
|
|
397
|
+
registerPopup(el, physicalSide) {
|
|
392
398
|
this.popupElement.set(el);
|
|
399
|
+
this.popupPhysicalSideSource.set(physicalSide);
|
|
393
400
|
return () => {
|
|
394
401
|
if (this.popupElement() === el) {
|
|
395
402
|
this.popupElement.set(undefined);
|
|
403
|
+
this.popupPhysicalSideSource.set(undefined);
|
|
396
404
|
}
|
|
397
405
|
};
|
|
398
406
|
}
|
|
@@ -1122,7 +1130,9 @@ class RdxMenuPopup {
|
|
|
1122
1130
|
// open submenu as "inside" its parent automatically — replacing the legacy `branches` registry.
|
|
1123
1131
|
this.floatingContext.setFloatingElement(this.elementRef.nativeElement);
|
|
1124
1132
|
const unregister = this.rootContext.registerTransitionElement(this.elementRef.nativeElement);
|
|
1125
|
-
|
|
1133
|
+
// Register the wrapper's PHYSICAL side (not the popup's logical `data-side` echo) so safe-polygon
|
|
1134
|
+
// geometry stays correct when opened with a logical `side="inline-start"` / `inline-end`.
|
|
1135
|
+
const unregisterPopup = this.rootContext.registerPopup(this.elementRef.nativeElement, this.wrapper?.physicalPlacedSide);
|
|
1126
1136
|
inject(DestroyRef).onDestroy(() => {
|
|
1127
1137
|
unregister();
|
|
1128
1138
|
unregisterPopup();
|
|
@@ -2376,8 +2386,9 @@ class RdxMenuSubTrigger {
|
|
|
2376
2386
|
const { handler, dispose } = createSafePolygonHandler({
|
|
2377
2387
|
reference,
|
|
2378
2388
|
floating: popup,
|
|
2379
|
-
//
|
|
2380
|
-
|
|
2389
|
+
// Physical side from context (live: unresolved at open, flips on collision). NOT the popup's
|
|
2390
|
+
// `data-side`, which is the logical `inline-*` echo the geometry can't interpret.
|
|
2391
|
+
side: () => this.submenuContext.popupPhysicalSide() ?? 'right',
|
|
2381
2392
|
x: this.lastPointer.x,
|
|
2382
2393
|
y: this.lastPointer.y,
|
|
2383
2394
|
onClose: () => this.scheduleClose(),
|
|
@@ -2522,6 +2533,20 @@ class RdxMenuSubTrigger {
|
|
|
2522
2533
|
onPointerLeave() {
|
|
2523
2534
|
clearTimeout(this.openTimer);
|
|
2524
2535
|
}
|
|
2536
|
+
/**
|
|
2537
|
+
* Backup cancellation for a `pointerleave` that Chrome can drop during a fast pointer sweep across
|
|
2538
|
+
* adjacent triggers, which would otherwise leave the delayed hover-open armed and open a stale
|
|
2539
|
+
* submenu for a trigger the pointer has already left (stranding the parent at `pointer-events: none`).
|
|
2540
|
+
* `pointerout` bubbles, so it also fires while crossing between the trigger's own descendants — those
|
|
2541
|
+
* (where `relatedTarget` is still inside the trigger) must not cancel the pending open. Base UI parity
|
|
2542
|
+
* (`guardStaleOpen`); safe on this single, hover-driven trigger.
|
|
2543
|
+
*/
|
|
2544
|
+
onPointerOut(event) {
|
|
2545
|
+
if (this.elementRef.nativeElement.contains(event.relatedTarget)) {
|
|
2546
|
+
return;
|
|
2547
|
+
}
|
|
2548
|
+
clearTimeout(this.openTimer);
|
|
2549
|
+
}
|
|
2525
2550
|
clearHighlight() {
|
|
2526
2551
|
this.isFocused.set(false);
|
|
2527
2552
|
this.clearParentActiveIndex();
|
|
@@ -2597,7 +2622,7 @@ class RdxMenuSubTrigger {
|
|
|
2597
2622
|
}
|
|
2598
2623
|
}
|
|
2599
2624
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxMenuSubTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
2600
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: RdxMenuSubTrigger, isStandalone: true, selector: "[rdxMenuSubTrigger]", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, nativeButton: { classPropertyName: "nativeButton", publicName: "nativeButton", isSignal: true, isRequired: false, transformFunction: null }, openOnHover: { classPropertyName: "openOnHover", publicName: "openOnHover", isSignal: true, isRequired: false, transformFunction: null }, delay: { classPropertyName: "delay", publicName: "delay", isSignal: true, isRequired: false, transformFunction: null }, closeDelay: { classPropertyName: "closeDelay", publicName: "closeDelay", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "menuitem" }, listeners: { "focus": "onFocus()", "blur": "onBlur()", "click": "onClick($event)", "keydown.enter": "onEnter($event)", "keydown.space": "onEnter($event)", "keydown.arrowleft": "onArrowLeft($event)", "keydown.arrowright": "onArrowRight($event)", "pointermove": "onPointerMove($event)", "pointerleave": "onPointerLeave()", "rdx-menu-subtrigger-clear-highlight": "clearHighlight()" }, properties: { "attr.type": "nativeButtonState() ? \"button\" : undefined", "attr.tabindex": "parentMenuRoot?.open() && highlighted() ? 0 : -1", "attr.aria-haspopup": "\"menu\"", "attr.aria-expanded": "submenuContext.isOpen()", "attr.aria-disabled": "effectiveDisabled() ? true : undefined", "attr.data-popup-open": "submenuContext.isOpen() ? \"\" : undefined", "attr.data-highlighted": "highlighted() ? \"\" : undefined", "attr.data-disabled": "effectiveDisabled() ? \"\" : undefined", "attr.data-label": "label() ?? undefined" } }, exportAs: ["rdxMenuSubTrigger"], hostDirectives: [{ directive: i1.RdxPopperAnchor }, { directive: i1$1.RdxCompositeListItem }], ngImport: i0 }); }
|
|
2625
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: RdxMenuSubTrigger, isStandalone: true, selector: "[rdxMenuSubTrigger]", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, nativeButton: { classPropertyName: "nativeButton", publicName: "nativeButton", isSignal: true, isRequired: false, transformFunction: null }, openOnHover: { classPropertyName: "openOnHover", publicName: "openOnHover", isSignal: true, isRequired: false, transformFunction: null }, delay: { classPropertyName: "delay", publicName: "delay", isSignal: true, isRequired: false, transformFunction: null }, closeDelay: { classPropertyName: "closeDelay", publicName: "closeDelay", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "menuitem" }, listeners: { "focus": "onFocus()", "blur": "onBlur()", "click": "onClick($event)", "keydown.enter": "onEnter($event)", "keydown.space": "onEnter($event)", "keydown.arrowleft": "onArrowLeft($event)", "keydown.arrowright": "onArrowRight($event)", "pointermove": "onPointerMove($event)", "pointerleave": "onPointerLeave()", "pointerout": "onPointerOut($event)", "rdx-menu-subtrigger-clear-highlight": "clearHighlight()" }, properties: { "attr.type": "nativeButtonState() ? \"button\" : undefined", "attr.tabindex": "parentMenuRoot?.open() && highlighted() ? 0 : -1", "attr.aria-haspopup": "\"menu\"", "attr.aria-expanded": "submenuContext.isOpen()", "attr.aria-disabled": "effectiveDisabled() ? true : undefined", "attr.data-popup-open": "submenuContext.isOpen() ? \"\" : undefined", "attr.data-highlighted": "highlighted() ? \"\" : undefined", "attr.data-disabled": "effectiveDisabled() ? \"\" : undefined", "attr.data-label": "label() ?? undefined" } }, exportAs: ["rdxMenuSubTrigger"], hostDirectives: [{ directive: i1.RdxPopperAnchor }, { directive: i1$1.RdxCompositeListItem }], ngImport: i0 }); }
|
|
2601
2626
|
}
|
|
2602
2627
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxMenuSubTrigger, decorators: [{
|
|
2603
2628
|
type: Directive,
|
|
@@ -2625,6 +2650,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImpor
|
|
|
2625
2650
|
'(keydown.arrowright)': 'onArrowRight($event)',
|
|
2626
2651
|
'(pointermove)': 'onPointerMove($event)',
|
|
2627
2652
|
'(pointerleave)': 'onPointerLeave()',
|
|
2653
|
+
'(pointerout)': 'onPointerOut($event)',
|
|
2628
2654
|
'(rdx-menu-subtrigger-clear-highlight)': 'clearHighlight()'
|
|
2629
2655
|
}
|
|
2630
2656
|
}]
|
|
@@ -2702,7 +2728,8 @@ class RdxMenuTrigger {
|
|
|
2702
2728
|
const { handler, dispose } = createSafePolygonHandler({
|
|
2703
2729
|
reference: trigger,
|
|
2704
2730
|
floating: popup,
|
|
2705
|
-
side
|
|
2731
|
+
// Physical side from context — the popup's `data-side` may be a logical `inline-*` echo.
|
|
2732
|
+
side: () => this.rootContext.popupPhysicalSide() ?? 'bottom',
|
|
2706
2733
|
x: this.lastPointer.x,
|
|
2707
2734
|
y: this.lastPointer.y,
|
|
2708
2735
|
onClose: () => this.scheduleClose(),
|