@radix-ng/primitives 1.0.9 → 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 +35 -19
- 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 +46 -21
- 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 +189 -26
- package/fesm2022/radix-ng-primitives-core.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-date-field.mjs +29 -13
- 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-floating-focus-manager.mjs +9 -0
- package/fesm2022/radix-ng-primitives-floating-focus-manager.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-focus-scope.mjs +241 -95
- package/fesm2022/radix-ng-primitives-focus-scope.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 +131 -16
- package/fesm2022/radix-ng-primitives-menu.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-navigation-menu.mjs +17 -3
- package/fesm2022/radix-ng-primitives-navigation-menu.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-popper.mjs +223 -29
- package/fesm2022/radix-ng-primitives-popper.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-portal.mjs +16 -5
- package/fesm2022/radix-ng-primitives-portal.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 +49 -17
- 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 +24 -10
- package/fesm2022/radix-ng-primitives-time-field.mjs.map +1 -1
- package/package.json +8 -7
- 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 +165 -104
- package/types/radix-ng-primitives-date-field.d.ts +21 -8
- package/types/radix-ng-primitives-field.d.ts +55 -8
- package/types/radix-ng-primitives-floating-focus-manager.d.ts +7 -0
- package/types/radix-ng-primitives-focus-scope.d.ts +61 -44
- 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 +59 -7
- 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 +186 -48
- package/types/radix-ng-primitives-portal.d.ts +18 -8
- 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 +21 -10
- package/types/radix-ng-primitives-tooltip.d.ts +2 -2
- package/fesm2022/radix-ng-primitives-focus-guards.mjs +0 -53
- package/fesm2022/radix-ng-primitives-focus-guards.mjs.map +0 -1
- package/focus-guards/README.md +0 -1
- package/types/radix-ng-primitives-focus-guards.d.ts +0 -15
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import {
|
|
2
|
+
import { InputSignal, InputSignalWithTransform, ModelSignal, OutputRef, Signal, Type, Provider, WritableSignal, ProviderToken, InjectionToken, OutputEmitterRef, Injector, ElementRef, EffectRef, EffectCleanupRegisterFn, CreateEffectOptions } from '@angular/core';
|
|
3
3
|
import { ControlValueAccessor } from '@angular/forms';
|
|
4
4
|
import { DateValue, Time, CalendarDateTime, ZonedDateTime } from '@internationalized/date';
|
|
5
5
|
import * as _radix_ng_primitives_core from '@radix-ng/primitives/core';
|
|
@@ -101,6 +101,114 @@ declare class RdxControlValueAccessor<T> implements ControlValueAccessor {
|
|
|
101
101
|
*/
|
|
102
102
|
declare function injectControlValueAccessor<T>(): RdxControlValueAccessor<T>;
|
|
103
103
|
|
|
104
|
+
/**
|
|
105
|
+
* Local mirror of Angular Signal Forms' control contracts
|
|
106
|
+
* (`@angular/forms/signals`, stable in Angular 22).
|
|
107
|
+
*
|
|
108
|
+
* These interfaces intentionally do **not** import from `@angular/forms/signals`,
|
|
109
|
+
* so control entries do not pull that optional integration into their public
|
|
110
|
+
* dependency graph. Primitives can still declare `implements RdxFormValueControl<T>` /
|
|
111
|
+
* `implements RdxFormCheckboxControl`; the mirror locks the public surface (the
|
|
112
|
+
* required `value` / `checked` signal) and catches naming regressions on CI — e.g.
|
|
113
|
+
* a rewrite renaming `value` → `modelValue` (as the slider once had) would no
|
|
114
|
+
* longer type-check.
|
|
115
|
+
*
|
|
116
|
+
* Optional state types are widened only where Radix NG controls legitimately
|
|
117
|
+
* differ from Angular's exact types (e.g. `input<string>()` produces
|
|
118
|
+
* `string | undefined`, and boolean inputs carry a coercion transform).
|
|
119
|
+
*
|
|
120
|
+
* The real Angular types stay isolated in `@radix-ng/primitives/signal-forms`.
|
|
121
|
+
* See ADR 0018 and `.claude/skills/project-knowledge/references/signal-forms-readiness.md`.
|
|
122
|
+
*/
|
|
123
|
+
/** An optional control-state member exposed as an Angular input signal (with or without a coercion transform). */
|
|
124
|
+
type RdxFormStateInput<T> = InputSignal<T> | InputSignalWithTransform<T, any>;
|
|
125
|
+
/**
|
|
126
|
+
* Minimal stand-in for Angular's `ValidationError`. The real type is a tagged
|
|
127
|
+
* union (`RequiredValidationError`, `PatternValidationError`, …); this keeps a
|
|
128
|
+
* shared shape until the v22 type is available.
|
|
129
|
+
*/
|
|
130
|
+
interface RdxValidationError {
|
|
131
|
+
readonly kind: string;
|
|
132
|
+
readonly message?: string;
|
|
133
|
+
}
|
|
134
|
+
/** Optional state shared by value and checkbox controls (mirror of Angular's `FormUiControl`). */
|
|
135
|
+
interface RdxFormUiControl {
|
|
136
|
+
readonly disabled?: RdxFormStateInput<boolean>;
|
|
137
|
+
readonly readonly?: RdxFormStateInput<boolean>;
|
|
138
|
+
readonly required?: RdxFormStateInput<boolean>;
|
|
139
|
+
readonly invalid?: RdxFormStateInput<boolean>;
|
|
140
|
+
readonly hidden?: RdxFormStateInput<boolean>;
|
|
141
|
+
readonly pending?: RdxFormStateInput<boolean>;
|
|
142
|
+
/**
|
|
143
|
+
* Touched status the form writes into the control.
|
|
144
|
+
*
|
|
145
|
+
* The two API generations disagree on the notification half: the 21.x
|
|
146
|
+
* experimental implementation listens to a `touched` **model**'s
|
|
147
|
+
* `touchedChange` output, while stable Angular 22 reverted to a plain
|
|
148
|
+
* `touched` input plus a separate {@link touch} output. A `model()` set on
|
|
149
|
+
* blur **plus** an emitted `touch` output satisfies both (`ModelSignal`
|
|
150
|
+
* extends `InputSignalWithTransform`, so it type-checks as the 22 input).
|
|
151
|
+
*/
|
|
152
|
+
readonly touched?: ModelSignal<boolean> | RdxFormStateInput<boolean> | OutputRef<boolean>;
|
|
153
|
+
readonly dirty?: RdxFormStateInput<boolean>;
|
|
154
|
+
readonly name?: RdxFormStateInput<string | undefined>;
|
|
155
|
+
readonly errors?: RdxFormStateInput<readonly RdxValidationError[]>;
|
|
156
|
+
readonly minLength?: RdxFormStateInput<number | undefined>;
|
|
157
|
+
readonly maxLength?: RdxFormStateInput<number | undefined>;
|
|
158
|
+
readonly pattern?: RdxFormStateInput<readonly RegExp[]>;
|
|
159
|
+
/** Notifies the form the control was touched (stable Angular 22 contract; ignored by 21.x). */
|
|
160
|
+
readonly touch?: OutputRef<void>;
|
|
161
|
+
/** Resets the control's UI state (optional method added in stable Angular 22). */
|
|
162
|
+
reset?(): void;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Mirror of `FormValueControl<TValue>` — a control that edits a single value via
|
|
166
|
+
* `value = model<TValue>()`. It must **not** expose `checked`.
|
|
167
|
+
*/
|
|
168
|
+
interface RdxFormValueControl<TValue> extends RdxFormUiControl {
|
|
169
|
+
readonly value: ModelSignal<TValue>;
|
|
170
|
+
readonly checked?: undefined;
|
|
171
|
+
readonly min?: RdxFormStateInput<NonNullable<TValue> | undefined>;
|
|
172
|
+
readonly max?: RdxFormStateInput<NonNullable<TValue> | undefined>;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Mirror of `FormCheckboxControl` — a control that toggles via
|
|
176
|
+
* `checked = model<boolean>()`. It must **not** expose `value`.
|
|
177
|
+
*/
|
|
178
|
+
interface RdxFormCheckboxControl extends RdxFormUiControl {
|
|
179
|
+
readonly checked: ModelSignal<boolean>;
|
|
180
|
+
readonly value?: undefined;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Form state owned by an Angular Reactive Forms or template-driven `NgControl` on the same host
|
|
185
|
+
* element. `connected` stays false for standalone and Signal Forms controls.
|
|
186
|
+
*
|
|
187
|
+
* @ignore
|
|
188
|
+
*/
|
|
189
|
+
interface RdxNgControlState {
|
|
190
|
+
readonly connected: Signal<boolean>;
|
|
191
|
+
readonly name: Signal<string | undefined>;
|
|
192
|
+
readonly value: Signal<unknown>;
|
|
193
|
+
readonly valid: Signal<boolean>;
|
|
194
|
+
readonly invalid: Signal<boolean>;
|
|
195
|
+
readonly pending: Signal<boolean>;
|
|
196
|
+
readonly disabled: Signal<boolean>;
|
|
197
|
+
readonly errors: Signal<readonly RdxValidationError[]>;
|
|
198
|
+
readonly dirty: Signal<boolean>;
|
|
199
|
+
readonly touched: Signal<boolean>;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Lazily connects to the same-host `NgControl` without creating a circular dependency while Angular
|
|
203
|
+
* is resolving its `ControlValueAccessor`. The unified `AbstractControl.events` stream mirrors
|
|
204
|
+
* programmatic value, status, validation, and interaction-state changes as well as user-driven ones.
|
|
205
|
+
*
|
|
206
|
+
* Must be called in an injection context.
|
|
207
|
+
*
|
|
208
|
+
* @ignore
|
|
209
|
+
*/
|
|
210
|
+
declare function injectNgControlState(): RdxNgControlState;
|
|
211
|
+
|
|
104
212
|
/**
|
|
105
213
|
* Include in the providers section of a component which utilizes ControlValueAccessor to redundant code.
|
|
106
214
|
*
|
|
@@ -453,21 +561,21 @@ declare function getSegmentElements(parentElement: HTMLElement): Element[];
|
|
|
453
561
|
type UseDateFieldProps = {
|
|
454
562
|
hasLeftFocus: WritableSignal<boolean>;
|
|
455
563
|
lastKeyZero: WritableSignal<boolean>;
|
|
456
|
-
placeholder:
|
|
457
|
-
hourCycle: HourCycle;
|
|
564
|
+
placeholder: Signal<DateValue>;
|
|
565
|
+
hourCycle: HourCycle | undefined;
|
|
458
566
|
formatter: Formatter;
|
|
459
567
|
segmentValues: WritableSignal<SegmentValueObj>;
|
|
460
568
|
step: Signal<DateStep>;
|
|
461
|
-
disabled:
|
|
462
|
-
readonly:
|
|
569
|
+
disabled: Signal<boolean>;
|
|
570
|
+
readonly: Signal<boolean>;
|
|
463
571
|
part: SegmentPart;
|
|
464
|
-
modelValue: ModelSignal<DateValue |
|
|
572
|
+
modelValue: ModelSignal<DateValue | null> | WritableSignal<DateValue | null>;
|
|
465
573
|
focusNext: () => void;
|
|
466
574
|
};
|
|
467
575
|
type SegmentAttrProps = {
|
|
468
576
|
disabled: boolean;
|
|
469
577
|
segmentValues: SegmentValueObj;
|
|
470
|
-
hourCycle: HourCycle;
|
|
578
|
+
hourCycle: HourCycle | undefined;
|
|
471
579
|
placeholder: DateValue;
|
|
472
580
|
formatter: Formatter;
|
|
473
581
|
};
|
|
@@ -763,104 +871,28 @@ declare function isEqual(a: any, b: any): boolean;
|
|
|
763
871
|
* of the specified class. This is especially useful when you want multiple
|
|
764
872
|
* tokens (or interfaces) to resolve to the same directive/component instance.
|
|
765
873
|
*
|
|
766
|
-
*
|
|
767
|
-
*
|
|
768
|
-
*
|
|
874
|
+
* `Type<T>` ties the class to the token's contract, so a class that does not
|
|
875
|
+
* satisfy `T` is rejected at compile time instead of failing at runtime.
|
|
876
|
+
*
|
|
877
|
+
* @template T - The type associated with the provider token.
|
|
878
|
+
* @param token - The token (InjectionToken, class, or abstract class) to provide.
|
|
879
|
+
* @param type - The class whose existing instance resolves this token; must satisfy `T`.
|
|
769
880
|
* @returns A Provider configuration object for Angular's DI system.
|
|
770
881
|
*
|
|
771
882
|
* @example
|
|
772
883
|
*
|
|
773
884
|
* @Directive({
|
|
774
885
|
* providers: [
|
|
775
|
-
*
|
|
886
|
+
* provideExistingToken(RdxFooToken, RdxFooDirective),
|
|
776
887
|
* provideValueAccessor(RdxFooDirective)
|
|
777
888
|
* ]
|
|
778
889
|
* })
|
|
779
890
|
* export class RdxFooDirective {}
|
|
780
891
|
*/
|
|
781
|
-
declare function
|
|
892
|
+
declare function provideExistingToken<T>(token: ProviderToken<T>, type: Type<T>): Provider;
|
|
782
893
|
|
|
783
894
|
/**
|
|
784
|
-
*
|
|
785
|
-
* (`@angular/forms/signals`, stable in Angular 22).
|
|
786
|
-
*
|
|
787
|
-
* These interfaces intentionally do **not** import from `@angular/forms/signals`
|
|
788
|
-
* so primitives can declare `implements RdxFormValueControl<T>` /
|
|
789
|
-
* `implements RdxFormCheckboxControl` while the library baseline is still on
|
|
790
|
-
* Angular 21, where the real API is experimental. They mirror Angular's contract
|
|
791
|
-
* closely enough to lock the public surface (the required `value` / `checked`
|
|
792
|
-
* signal) and catch naming regressions on CI — e.g. a rewrite renaming
|
|
793
|
-
* `value` → `modelValue` (as the slider once had) would no longer type-check.
|
|
794
|
-
*
|
|
795
|
-
* Optional state types are widened only where Radix NG controls legitimately
|
|
796
|
-
* differ from Angular's exact types (e.g. `input<string>()` produces
|
|
797
|
-
* `string | undefined`, and boolean inputs carry a coercion transform).
|
|
798
|
-
*
|
|
799
|
-
* Replace with the real imports once the baseline moves to Angular 22.
|
|
800
|
-
* See `.claude/skills/project-knowledge/references/signal-forms-readiness.md`.
|
|
801
|
-
*/
|
|
802
|
-
/** An optional control-state member exposed as an Angular input signal (with or without a coercion transform). */
|
|
803
|
-
type RdxFormStateInput<T> = InputSignal<T> | InputSignalWithTransform<T, any>;
|
|
804
|
-
/**
|
|
805
|
-
* Minimal stand-in for Angular's `ValidationError`. The real type is a tagged
|
|
806
|
-
* union (`RequiredValidationError`, `PatternValidationError`, …); this keeps a
|
|
807
|
-
* shared shape until the v22 type is available.
|
|
808
|
-
*/
|
|
809
|
-
interface RdxValidationError {
|
|
810
|
-
readonly kind: string;
|
|
811
|
-
readonly message?: string;
|
|
812
|
-
}
|
|
813
|
-
/** Optional state shared by value and checkbox controls (mirror of Angular's `FormUiControl`). */
|
|
814
|
-
interface RdxFormUiControl {
|
|
815
|
-
readonly disabled?: RdxFormStateInput<boolean>;
|
|
816
|
-
readonly readonly?: RdxFormStateInput<boolean>;
|
|
817
|
-
readonly required?: RdxFormStateInput<boolean>;
|
|
818
|
-
readonly invalid?: RdxFormStateInput<boolean>;
|
|
819
|
-
readonly hidden?: RdxFormStateInput<boolean>;
|
|
820
|
-
readonly pending?: RdxFormStateInput<boolean>;
|
|
821
|
-
/**
|
|
822
|
-
* Touched status the form writes into the control.
|
|
823
|
-
*
|
|
824
|
-
* The two API generations disagree on the notification half: the 21.x
|
|
825
|
-
* experimental implementation listens to a `touched` **model**'s
|
|
826
|
-
* `touchedChange` output, while stable Angular 22 reverted to a plain
|
|
827
|
-
* `touched` input plus a separate {@link touch} output. A `model()` set on
|
|
828
|
-
* blur **plus** an emitted `touch` output satisfies both (`ModelSignal`
|
|
829
|
-
* extends `InputSignalWithTransform`, so it type-checks as the 22 input).
|
|
830
|
-
*/
|
|
831
|
-
readonly touched?: ModelSignal<boolean> | RdxFormStateInput<boolean> | OutputRef<boolean>;
|
|
832
|
-
readonly dirty?: RdxFormStateInput<boolean>;
|
|
833
|
-
readonly name?: RdxFormStateInput<string | undefined>;
|
|
834
|
-
readonly errors?: RdxFormStateInput<readonly RdxValidationError[]>;
|
|
835
|
-
readonly minLength?: RdxFormStateInput<number | undefined>;
|
|
836
|
-
readonly maxLength?: RdxFormStateInput<number | undefined>;
|
|
837
|
-
readonly pattern?: RdxFormStateInput<readonly RegExp[]>;
|
|
838
|
-
/** Notifies the form the control was touched (stable Angular 22 contract; ignored by 21.x). */
|
|
839
|
-
readonly touch?: OutputRef<void>;
|
|
840
|
-
/** Resets the control's UI state (optional method added in stable Angular 22). */
|
|
841
|
-
reset?(): void;
|
|
842
|
-
}
|
|
843
|
-
/**
|
|
844
|
-
* Mirror of `FormValueControl<TValue>` — a control that edits a single value via
|
|
845
|
-
* `value = model<TValue>()`. It must **not** expose `checked`.
|
|
846
|
-
*/
|
|
847
|
-
interface RdxFormValueControl<TValue> extends RdxFormUiControl {
|
|
848
|
-
readonly value: ModelSignal<TValue>;
|
|
849
|
-
readonly checked?: undefined;
|
|
850
|
-
readonly min?: RdxFormStateInput<NonNullable<TValue> | undefined>;
|
|
851
|
-
readonly max?: RdxFormStateInput<NonNullable<TValue> | undefined>;
|
|
852
|
-
}
|
|
853
|
-
/**
|
|
854
|
-
* Mirror of `FormCheckboxControl` — a control that toggles via
|
|
855
|
-
* `checked = model<boolean>()`. It must **not** expose `value`.
|
|
856
|
-
*/
|
|
857
|
-
interface RdxFormCheckboxControl extends RdxFormUiControl {
|
|
858
|
-
readonly checked: ModelSignal<boolean>;
|
|
859
|
-
readonly value?: undefined;
|
|
860
|
-
}
|
|
861
|
-
|
|
862
|
-
/**
|
|
863
|
-
* Optional form-control UI state derived from a control's `invalid`/`errors`/`touched`/`dirty`
|
|
895
|
+
* Optional form-control UI state derived from a control's `invalid`/`pending`/`errors`/`touched`/`dirty`
|
|
864
896
|
* inputs (the optional members of Signal Forms' `FormUiControl`), plus the two mutators every
|
|
865
897
|
* control needs.
|
|
866
898
|
*
|
|
@@ -869,6 +901,12 @@ interface RdxFormCheckboxControl extends RdxFormUiControl {
|
|
|
869
901
|
interface RdxFormUiState {
|
|
870
902
|
/** Invalid when the `invalid` input is set or the `errors` list is non-empty. */
|
|
871
903
|
readonly invalidState: Signal<boolean>;
|
|
904
|
+
/** Whether asynchronous validation is still settling. Pending is neither valid nor invalid. */
|
|
905
|
+
readonly pendingState: Signal<boolean>;
|
|
906
|
+
/** Tri-state validity: valid / invalid / neutral while pending or disabled. */
|
|
907
|
+
readonly validState: Signal<boolean | null>;
|
|
908
|
+
/** Explicit control errors merged with same-host Angular Forms errors. */
|
|
909
|
+
readonly errorsState: Signal<readonly RdxValidationError[]>;
|
|
872
910
|
/** Whether the control has been touched (reflects the `touched` model). */
|
|
873
911
|
readonly touchedState: Signal<boolean>;
|
|
874
912
|
/** Whether the value changed from its initial value — external `dirty` OR internal tracking. */
|
|
@@ -877,6 +915,10 @@ interface RdxFormUiState {
|
|
|
877
915
|
markAsTouched(): void;
|
|
878
916
|
/** Flag the control dirty after a value change (feeds {@link dirtyState}). */
|
|
879
917
|
markDirty(): void;
|
|
918
|
+
/** Clear control-owned touched/dirty state when a form resets it. */
|
|
919
|
+
resetInteractionState?(): void;
|
|
920
|
+
/** Clear only control-owned dirty state when the form marks the field pristine. */
|
|
921
|
+
resetDirtyState?(): void;
|
|
880
922
|
}
|
|
881
923
|
/** Minimal `ControlValueAccessor` surface the form-UI state bridges for the dual (Reactive/template) path. */
|
|
882
924
|
interface RdxFormUiTouchTarget {
|
|
@@ -885,20 +927,24 @@ interface RdxFormUiTouchTarget {
|
|
|
885
927
|
/** Inputs a control passes to {@link createFormUiState} — its own `FormUiControl` signals. */
|
|
886
928
|
interface RdxFormUiStateOptions {
|
|
887
929
|
readonly invalid: Signal<boolean>;
|
|
930
|
+
/** Optional for backwards compatibility with custom controls authored before pending support. */
|
|
931
|
+
readonly pending?: Signal<boolean>;
|
|
888
932
|
readonly errors: Signal<readonly RdxValidationError[]>;
|
|
889
933
|
readonly touched: ModelSignal<boolean>;
|
|
890
934
|
readonly touch: OutputEmitterRef<void>;
|
|
891
935
|
readonly dirty: Signal<boolean>;
|
|
936
|
+
/** Same-host Reactive/template-driven form interaction state, when one is present. */
|
|
937
|
+
readonly ngControlState?: RdxNgControlState | null;
|
|
892
938
|
/**
|
|
893
939
|
* The control's `ControlValueAccessor`, if it has one (dual controls — switch, number-field, …).
|
|
894
|
-
* Omit or pass `null` for Signal-Forms-only controls without a CVA (e.g.
|
|
940
|
+
* Omit or pass `null` for Signal-Forms-only controls without a CVA (e.g. date-field).
|
|
895
941
|
*/
|
|
896
942
|
readonly cva?: RdxFormUiTouchTarget | null;
|
|
897
943
|
}
|
|
898
944
|
/**
|
|
899
945
|
* Builds the shared form-UI state and its mutators from a control's input signals, removing the
|
|
900
|
-
* per-control copy-paste of the
|
|
901
|
-
*
|
|
946
|
+
* per-control copy-paste of the validation/interaction computeds and the `markAsTouched`/`markDirty`
|
|
947
|
+
* logic.
|
|
902
948
|
*
|
|
903
949
|
* **Why the inputs stay on the control (not in here):** Angular's compiler only discovers
|
|
904
950
|
* `input()`/`model()` declared as field initializers, and Signal Forms binds form-written state
|
|
@@ -916,6 +962,8 @@ declare function createFormUiState(options: RdxFormUiStateOptions): RdxFormUiSta
|
|
|
916
962
|
*/
|
|
917
963
|
interface RdxFormUiStateContext {
|
|
918
964
|
invalidState: Signal<boolean>;
|
|
965
|
+
pendingState: Signal<boolean>;
|
|
966
|
+
validState: Signal<boolean | null>;
|
|
919
967
|
touchedState: Signal<boolean>;
|
|
920
968
|
dirtyState: Signal<boolean>;
|
|
921
969
|
markAsTouched: () => void;
|
|
@@ -936,14 +984,14 @@ declare const RDX_FIELD_VALIDITY: InjectionToken<Signal<boolean | null>>;
|
|
|
936
984
|
/**
|
|
937
985
|
* Tri-state display validity: when inside a `Field` the field's gated `validState` is the **single
|
|
938
986
|
* source** (the control reflects it, including its `validationMode` neutral state); standalone, the
|
|
939
|
-
* control's own
|
|
987
|
+
* control's own tri-state validity (pending is neutral).
|
|
940
988
|
*
|
|
941
989
|
* **Contract:** inside a `Field` a control's own `invalid` / `errors` inputs are **not** displayed — the
|
|
942
990
|
* Field owns displayed validity. Drive validity through the Field instead: bind `rdxSignalField`
|
|
943
991
|
* (Signal Forms), or set `[invalid]` on `rdxFieldRoot`. The control's own `invalid`/`errors` are for
|
|
944
992
|
* standalone use.
|
|
945
993
|
*/
|
|
946
|
-
declare function resolveDisplayValid(fieldValidity: Signal<boolean | null> | null, ownInvalid: Signal<boolean>): boolean | null;
|
|
994
|
+
declare function resolveDisplayValid(fieldValidity: Signal<boolean | null> | null, ownInvalid: Signal<boolean>, ownPending?: Signal<boolean>): boolean | null;
|
|
947
995
|
/**
|
|
948
996
|
* Provide a control's {@link RdxFormUiState} on its host element so {@link RdxFormUiStateHost} can
|
|
949
997
|
* reflect it. Pair with `hostDirectives: [RdxFormUiStateHost]`:
|
|
@@ -982,7 +1030,7 @@ declare class RdxFormUiStateHost {
|
|
|
982
1030
|
}
|
|
983
1031
|
/**
|
|
984
1032
|
* Abstract base that declares the optional `FormUiControl` state inputs
|
|
985
|
-
* (`invalid`/`errors`/`touched`/`dirty` + the `touch` output) once and builds the control's
|
|
1033
|
+
* (`invalid`/`pending`/`errors`/`touched`/`dirty` + the `touch` output) once and builds the control's
|
|
986
1034
|
* {@link RdxFormUiState} from them, so a control directive can inherit the whole surface with a
|
|
987
1035
|
* single `extends` instead of re-declaring it.
|
|
988
1036
|
*
|
|
@@ -999,6 +1047,8 @@ declare class RdxFormUiStateHost {
|
|
|
999
1047
|
declare abstract class RdxFormUiControlBase {
|
|
1000
1048
|
/** Whether the control is invalid. A non-empty {@link errors} list also marks it invalid. */
|
|
1001
1049
|
readonly invalid: i0.InputSignalWithTransform<boolean, BooleanInput>;
|
|
1050
|
+
/** Whether async validation is pending. Pending controls publish neither `data-valid` nor `data-invalid`. */
|
|
1051
|
+
readonly pending: i0.InputSignalWithTransform<boolean, BooleanInput>;
|
|
1002
1052
|
/** Whether the control has been touched. A `model()` so Signal Forms can write it; set on blur/focus-out. */
|
|
1003
1053
|
readonly touched: ModelSignal<boolean>;
|
|
1004
1054
|
/** Whether the value changed from its initial value. Merged with internal tracking. */
|
|
@@ -1007,8 +1057,12 @@ declare abstract class RdxFormUiControlBase {
|
|
|
1007
1057
|
readonly errors: i0.InputSignal<readonly RdxValidationError[]>;
|
|
1008
1058
|
/** Emits when the control is touched, notifying Signal Forms (stable Angular 22 contract). */
|
|
1009
1059
|
readonly touch: OutputEmitterRef<void>;
|
|
1060
|
+
private readonly ngControlState;
|
|
1010
1061
|
/** The shared form-UI state derived from the inputs above. Call `formUi.markDirty()` on value change. */
|
|
1011
1062
|
readonly formUi: RdxFormUiState;
|
|
1063
|
+
/** Validation errors from the control inputs and a same-host Reactive/template-driven form control. */
|
|
1064
|
+
readonly validationErrors: Signal<readonly RdxValidationError[]>;
|
|
1065
|
+
constructor();
|
|
1012
1066
|
/** The enclosing Field's tri-state display validity, if any. `protected` so a control whose own
|
|
1013
1067
|
* invalidity is richer than `formUi.invalidState` (e.g. date/time-field add a parse check) can build
|
|
1014
1068
|
* its own `displayValid` from it. */
|
|
@@ -1016,19 +1070,26 @@ declare abstract class RdxFormUiControlBase {
|
|
|
1016
1070
|
/**
|
|
1017
1071
|
* Tri-state *displayed* validity for controls that bind their own host attributes (radio, switch,
|
|
1018
1072
|
* number-field): the enclosing Field's gated state when inside a `rdxFieldRoot`, else this control's
|
|
1019
|
-
* own
|
|
1073
|
+
* own validity (`formUi.pendingState` is neutral; otherwise `formUi.invalidState` is binary). Bind
|
|
1074
|
+
* `data-valid`/`data-invalid`/`aria-invalid` to
|
|
1020
1075
|
* this so a neutral field shows neither. Controls whose `invalidState` is richer than
|
|
1021
|
-
* `formUi.invalidState` override this with
|
|
1076
|
+
* `formUi.invalidState` override this with
|
|
1077
|
+
* `resolveDisplayValid(this.fieldValidity, this.invalidState, this.formUi.pendingState)`.
|
|
1022
1078
|
*/
|
|
1023
1079
|
readonly displayValid: Signal<boolean | null>;
|
|
1024
1080
|
/**
|
|
1025
1081
|
* Override to bridge the control's `ControlValueAccessor` into `markAsTouched` (dual controls —
|
|
1026
1082
|
* return `injectControlValueAccessor()` or a `{ markAsTouched }` adapter). Default: no CVA
|
|
1027
|
-
* (Signal-Forms-only controls such as
|
|
1083
|
+
* (Signal-Forms-only controls such as date-field).
|
|
1028
1084
|
*/
|
|
1029
1085
|
protected formUiTouchTarget(): RdxFormUiTouchTarget | null;
|
|
1086
|
+
/**
|
|
1087
|
+
* Reset control-owned interaction state. Angular Signal Forms calls this optional custom-control
|
|
1088
|
+
* hook from `FieldState.reset()` after restoring the field value.
|
|
1089
|
+
*/
|
|
1090
|
+
reset(): void;
|
|
1030
1091
|
static ɵfac: i0.ɵɵFactoryDeclaration<RdxFormUiControlBase, never>;
|
|
1031
|
-
static ɵdir: i0.ɵɵDirectiveDeclaration<RdxFormUiControlBase, never, never, { "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "dirty": { "alias": "dirty"; "required": false; "isSignal": true; }; "errors": { "alias": "errors"; "required": false; "isSignal": true; }; }, { "touched": "touchedChange"; "touch": "touch"; }, never, never, true, never>;
|
|
1092
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<RdxFormUiControlBase, never, never, { "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "pending": { "alias": "pending"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "dirty": { "alias": "dirty"; "required": false; "isSignal": true; }; "errors": { "alias": "errors"; "required": false; "isSignal": true; }; }, { "touched": "touchedChange"; "touch": "touch"; }, never, never, true, never>;
|
|
1032
1093
|
}
|
|
1033
1094
|
|
|
1034
1095
|
/**
|
|
@@ -2053,5 +2114,5 @@ declare enum RdxPositionAlign {
|
|
|
2053
2114
|
End = "end"
|
|
2054
2115
|
}
|
|
2055
2116
|
|
|
2056
|
-
export { A, ALT, ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT, ARROW_UP, ASTERISK, BACKSPACE, CAPS_LOCK, CONTROL, CTRL, DELETE, DOCS_BASE_URL, END, ENTER, ESCAPE, F1, F10, F11, F12, F2, F3, F4, F5, F6, F7, F8, F9, HOME, META, P, PAGE_DOWN, PAGE_UP, RDX_DEFAULT_VALIDATION_MODE, RDX_FIELD_VALIDITY, RDX_FLOATING_REGISTRATION, RDX_FLOATING_ROOT_CONTEXT, RDX_FLOATING_TREE, RDX_FORM_UI_STATE, RDX_INTERNAL_BACKDROP_ATTR, RDX_SCROLL_LOCKED_ATTR, RdxControlValueAccessor, RdxFloatingNode, RdxFloatingNodeRegistration, RdxFloatingRegistrationContext, RdxFloatingRootContext, RdxFloatingTree, RdxFormUiControlBase, RdxFormUiStateHost, RdxIdGenerator, RdxLiveAnnouncer, RdxPositionAlign, RdxPositionSide, RdxTriggerRegistry, SHIFT, SPACE, SPACE_CODE, TAB, TIME_GRANULARITIES, a, areAllDaysBetweenValid, clamp, createCancelableChangeEventDetails, createContent, createContext, createFloatingEvents, createFloatingRootContext, createFormUiState, createFormatter, createMonth, createMonths, docsUrl, elementSize, formUiStateContext, getActiveElement, getDaysBetween, getDaysInMonth, getDefaultDate, getDefaultTime, getLastFirstDayOfWeek, getMaxTransitionDuration, getNextLastDayOfWeek, getOptsByGranularity, getPlaceholder, getSegmentElements, getWeekNumber, handleAndDispatchCustomEvent, handleCalendarInitialFocus, hasTime, initializeSegmentValues, injectControlValueAccessor, injectDocument, injectFloatingRootContext, injectId, isAcceptableSegmentKey, isAfter, isAfterOrSame, isBefore, isBeforeOrSame, isBetween, isBetweenInclusive, isCalendarDateTime, isEqual, isItemEqualToValue, isNullish, isNumberString, isSegmentNavigationKey, isValidationRevealed, isZonedDateTime, itemToStringLabel, itemToStringValue, j, k, n, normalizeDateStep, normalizeHour12, normalizeHourCycle, p, provideFloatingRegistration, provideFloatingRootContext, provideFloatingTree, provideFormUiState,
|
|
2057
|
-
export type { AcceptableValue, AnyExceptLiteral, AriaLivePoliteness, BooleanInput, CreateMonthProps, DataOrientation, DateAndTimeSegmentObj, DateFormatterOptions, DateMatcher, DateRange, DateSegmentObj, DateSegmentPart, DateStep, DayPeriod, Direction, EditableSegmentPart, FilterPredicates, Formatter, Granularity, HourCycle, InjectContext, ItemValueComparator, ListHighlight, Month, NonEditableSegmentPart, Nullable, NumberInput, PlaceholderMap, RdxAnchoredScrollLockOptions, RdxCancelableChangeEventDetails, RdxCancelableChangeEventTransaction, RdxFloatingEventMap, RdxFloatingEvents, RdxFloatingLifecycle, RdxFloatingNodeInit, RdxFloatingParentOverride, RdxFloatingRegistrationReader, RdxFloatingRegistrationStatus, RdxFloatingRootContextEventMap, RdxFloatingRootContextInit, RdxFormCheckboxControl, RdxFormStateInput, RdxFormUiControl, RdxFormUiState, RdxFormUiStateContext, RdxFormUiStateOptions, RdxFormUiTouchTarget, RdxFormValueControl, RdxInternalBackdropOptions, RdxPointerDragHandlers, RdxScrollLockOptions, RdxTransitionStatus, RdxTransitionStatusRef, RdxValidationError, RdxValidationInteraction, RdxValidationMode, SafeFunction, SegmentContentObj, SegmentPart, SegmentValueObj, TimeGranularity, TimeSegmentObj, TimeSegmentPart, TimeValue, UseDateFieldProps, UseFilterOptions, UseListHighlightOptions };
|
|
2117
|
+
export { A, ALT, ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT, ARROW_UP, ASTERISK, BACKSPACE, CAPS_LOCK, CONTROL, CTRL, DELETE, DOCS_BASE_URL, END, ENTER, ESCAPE, F1, F10, F11, F12, F2, F3, F4, F5, F6, F7, F8, F9, HOME, META, P, PAGE_DOWN, PAGE_UP, RDX_DEFAULT_VALIDATION_MODE, RDX_FIELD_VALIDITY, RDX_FLOATING_REGISTRATION, RDX_FLOATING_ROOT_CONTEXT, RDX_FLOATING_TREE, RDX_FORM_UI_STATE, RDX_INTERNAL_BACKDROP_ATTR, RDX_SCROLL_LOCKED_ATTR, RdxControlValueAccessor, RdxFloatingNode, RdxFloatingNodeRegistration, RdxFloatingRegistrationContext, RdxFloatingRootContext, RdxFloatingTree, RdxFormUiControlBase, RdxFormUiStateHost, RdxIdGenerator, RdxLiveAnnouncer, RdxPositionAlign, RdxPositionSide, RdxTriggerRegistry, SHIFT, SPACE, SPACE_CODE, TAB, TIME_GRANULARITIES, a, areAllDaysBetweenValid, clamp, createCancelableChangeEventDetails, createContent, createContext, createFloatingEvents, createFloatingRootContext, createFormUiState, createFormatter, createMonth, createMonths, docsUrl, elementSize, formUiStateContext, getActiveElement, getDaysBetween, getDaysInMonth, getDefaultDate, getDefaultTime, getLastFirstDayOfWeek, getMaxTransitionDuration, getNextLastDayOfWeek, getOptsByGranularity, getPlaceholder, getSegmentElements, getWeekNumber, handleAndDispatchCustomEvent, handleCalendarInitialFocus, hasTime, initializeSegmentValues, injectControlValueAccessor, injectDocument, injectFloatingRootContext, injectId, injectNgControlState, isAcceptableSegmentKey, isAfter, isAfterOrSame, isBefore, isBeforeOrSame, isBetween, isBetweenInclusive, isCalendarDateTime, isEqual, isItemEqualToValue, isNullish, isNumberString, isSegmentNavigationKey, isValidationRevealed, isZonedDateTime, itemToStringLabel, itemToStringValue, j, k, n, normalizeDateStep, normalizeHour12, normalizeHourCycle, p, provideExistingToken, provideFloatingRegistration, provideFloatingRootContext, provideFloatingTree, provideFormUiState, provideValueAccessor, rdxCheckLabelElement, rdxCheckTriggerElement, rdxDevError, rdxDevWarning, resetRdxDevWarnings, resizeEffect, resolveDisplayValid, resolveFloatingTree, roundToStepPrecision, segmentBuilders, setupInternalBackdrop, snapValueToStep, syncSegmentValues, syncTimeSegmentValues, toDate, useAnchoredScrollLock, useArrowNavigation, useDateField, useFilter, useGraceArea, useListHighlight, usePointerDrag, useScrollLock, useTransitionStatus, watch };
|
|
2118
|
+
export type { AcceptableValue, AnyExceptLiteral, AriaLivePoliteness, BooleanInput, CreateMonthProps, DataOrientation, DateAndTimeSegmentObj, DateFormatterOptions, DateMatcher, DateRange, DateSegmentObj, DateSegmentPart, DateStep, DayPeriod, Direction, EditableSegmentPart, FilterPredicates, Formatter, Granularity, HourCycle, InjectContext, ItemValueComparator, ListHighlight, Month, NonEditableSegmentPart, Nullable, NumberInput, PlaceholderMap, RdxAnchoredScrollLockOptions, RdxCancelableChangeEventDetails, RdxCancelableChangeEventTransaction, RdxFloatingEventMap, RdxFloatingEvents, RdxFloatingLifecycle, RdxFloatingNodeInit, RdxFloatingParentOverride, RdxFloatingRegistrationReader, RdxFloatingRegistrationStatus, RdxFloatingRootContextEventMap, RdxFloatingRootContextInit, RdxFormCheckboxControl, RdxFormStateInput, RdxFormUiControl, RdxFormUiState, RdxFormUiStateContext, RdxFormUiStateOptions, RdxFormUiTouchTarget, RdxFormValueControl, RdxInternalBackdropOptions, RdxNgControlState, RdxPointerDragHandlers, RdxScrollLockOptions, RdxTransitionStatus, RdxTransitionStatusRef, RdxValidationError, RdxValidationInteraction, RdxValidationMode, SafeFunction, SegmentContentObj, SegmentPart, SegmentValueObj, TimeGranularity, TimeSegmentObj, TimeSegmentPart, TimeValue, UseDateFieldProps, UseFilterOptions, UseListHighlightOptions };
|
|
@@ -4,11 +4,12 @@ import * as _radix_ng_primitives_core from '@radix-ng/primitives/core';
|
|
|
4
4
|
import { RdxFormUiControlBase, RdxFormValueControl, DateMatcher, HourCycle, Granularity, Direction, BooleanInput, DateStep, Formatter, SegmentValueObj, SegmentPart } from '@radix-ng/primitives/core';
|
|
5
5
|
import { DateValue } from '@internationalized/date';
|
|
6
6
|
|
|
7
|
-
declare class RdxDateFieldRootDirective extends RdxFormUiControlBase implements RdxFormValueControl<DateValue |
|
|
7
|
+
declare class RdxDateFieldRootDirective extends RdxFormUiControlBase implements RdxFormValueControl<DateValue | null> {
|
|
8
8
|
/**
|
|
9
|
-
* The controlled value of the date field.
|
|
9
|
+
* The controlled value of the date field. `null` represents an empty field and keeps the value
|
|
10
|
+
* addressable as an Angular Signal Forms child field (`undefined` denotes an absent optional path).
|
|
10
11
|
*/
|
|
11
|
-
readonly value: _angular_core.ModelSignal<DateValue |
|
|
12
|
+
readonly value: _angular_core.ModelSignal<DateValue | null>;
|
|
12
13
|
/**
|
|
13
14
|
* A matcher that marks specific dates as unavailable; a matched value makes the field invalid.
|
|
14
15
|
*/
|
|
@@ -64,6 +65,13 @@ declare class RdxDateFieldRootDirective extends RdxFormUiControlBase implements
|
|
|
64
65
|
* The placeholder date, which is used to determine what month to display when no date is selected. This updates as the user navigates the calendar and can be used to programmatically control the calendar view
|
|
65
66
|
*/
|
|
66
67
|
readonly placeholder: _angular_core.ModelSignal<DateValue | undefined>;
|
|
68
|
+
/**
|
|
69
|
+
* Always-defined placeholder used for segment math. A controlled `[placeholder]` can be reset to
|
|
70
|
+
* `undefined`; fall back to the default date so segment attributes and key handlers never
|
|
71
|
+
* dereference `undefined`.
|
|
72
|
+
* @ignore
|
|
73
|
+
*/
|
|
74
|
+
readonly effectivePlaceholder: Signal<DateValue>;
|
|
67
75
|
/**
|
|
68
76
|
* Segment input parts, collected from the projected content in DOM order. This
|
|
69
77
|
* stays in sync with `segmentContents()` (granularity / locale / value changes
|
|
@@ -115,6 +123,8 @@ declare class RdxDateFieldRootDirective extends RdxFormUiControlBase implements
|
|
|
115
123
|
private readonly userInteracted;
|
|
116
124
|
/** @ignore Mark the field touched (model + `touch` output) for Signal Forms. Called on segment blur. */
|
|
117
125
|
markAsTouched(): void;
|
|
126
|
+
/** Reset segment interaction so the form-owned value write remains pristine. */
|
|
127
|
+
reset(): void;
|
|
118
128
|
/**
|
|
119
129
|
* @ignore
|
|
120
130
|
*/
|
|
@@ -228,16 +238,19 @@ declare class RdxDateFieldInputDirective {
|
|
|
228
238
|
|
|
229
239
|
interface DateFieldContextToken {
|
|
230
240
|
locale: InputSignal<string>;
|
|
231
|
-
value: ModelSignal<DateValue |
|
|
232
|
-
disabled:
|
|
233
|
-
readonly:
|
|
241
|
+
value: ModelSignal<DateValue | null>;
|
|
242
|
+
disabled: Signal<boolean>;
|
|
243
|
+
readonly: Signal<boolean>;
|
|
234
244
|
isInvalid: Signal<boolean>;
|
|
235
245
|
/** Effective invalid: the built-in range/availability check OR the form-driven invalid state. */
|
|
236
246
|
invalidState: Signal<boolean>;
|
|
237
247
|
/** Tri-state displayed validity (`true`/`false`/`null`): the field's gated state inside a Field, else own. */
|
|
238
248
|
displayValid: Signal<boolean | null>;
|
|
239
|
-
placeholder
|
|
240
|
-
|
|
249
|
+
/** The controlled placeholder; may be `undefined`. Use `effectivePlaceholder` for segment math. */
|
|
250
|
+
placeholder: Signal<DateValue | undefined>;
|
|
251
|
+
/** Always-defined placeholder (falls back to the default date) for segment attributes/key handlers. */
|
|
252
|
+
effectivePlaceholder: Signal<DateValue>;
|
|
253
|
+
hourCycle: Signal<HourCycle | undefined>;
|
|
241
254
|
step$: Signal<DateStep>;
|
|
242
255
|
formatter: Signal<Formatter>;
|
|
243
256
|
segmentValues: WritableSignal<SegmentValueObj>;
|
|
@@ -63,6 +63,15 @@ declare class RdxFieldError {
|
|
|
63
63
|
* @group Props
|
|
64
64
|
*/
|
|
65
65
|
readonly id: _angular_core.InputSignal<string>;
|
|
66
|
+
/**
|
|
67
|
+
* Shows this error only for a matching validation-error key. Bind `true` to keep it visible under
|
|
68
|
+
* external control; omit it for the field's default error behavior.
|
|
69
|
+
*
|
|
70
|
+
* @group Props
|
|
71
|
+
*/
|
|
72
|
+
readonly match: _angular_core.InputSignal<string | boolean | undefined>;
|
|
73
|
+
/** Whether this error part is currently presented. */
|
|
74
|
+
readonly visible: _angular_core.Signal<boolean>;
|
|
66
75
|
/**
|
|
67
76
|
* The field's validation messages — client (provider / form name-routing, once `validationMode`
|
|
68
77
|
* reveals them) then server (the Form's `errors` input, always); `[]` when none. Render them
|
|
@@ -73,12 +82,11 @@ declare class RdxFieldError {
|
|
|
73
82
|
constructor();
|
|
74
83
|
protected readonly dataAttr: (value: boolean) => "" | undefined;
|
|
75
84
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxFieldError, never>;
|
|
76
|
-
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxFieldError, "[rdxFieldError]", ["rdxFieldError"], { "id": { "alias": "id"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
85
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxFieldError, "[rdxFieldError]", ["rdxFieldError"], { "id": { "alias": "id"; "required": false; "isSignal": true; }; "match": { "alias": "match"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
77
86
|
}
|
|
78
87
|
|
|
79
88
|
/**
|
|
80
|
-
* External owner of field state. An adapter (
|
|
81
|
-
* `[rdxSignalField]` directive, or a Reactive Forms bridge) registers one via
|
|
89
|
+
* External owner of field state. An adapter (`rdxSignalField` or `rdxNgControlField`) registers one via
|
|
82
90
|
* `setStateProvider` so Field reads authoritative form state instead of
|
|
83
91
|
* self-computing it from the DOM. Each member is an optional signal-like
|
|
84
92
|
* accessor; only the states the adapter owns need to be provided — the rest
|
|
@@ -86,15 +94,19 @@ declare class RdxFieldError {
|
|
|
86
94
|
* `() => boolean` accessors keeps Field framework-agnostic (no dependency on
|
|
87
95
|
* `@angular/forms/signals`).
|
|
88
96
|
*
|
|
89
|
-
* See ADR 0004 and `signal-forms-readiness.md` (prep #4).
|
|
97
|
+
* See ADR 0004, ADR 0021, and `signal-forms-readiness.md` (prep #4).
|
|
90
98
|
*/
|
|
91
99
|
interface RdxFieldState {
|
|
100
|
+
/** Field name inferred by an adapter. An explicit `rdxFieldRoot[name]` always wins. */
|
|
101
|
+
name?: () => string | undefined;
|
|
92
102
|
/**
|
|
93
103
|
* The control's **actual** invalidity (ungated). The Field decides *when* to display it from its
|
|
94
104
|
* `validationMode` (e.g. only after blur) — the adapter just reports the real state. A non-empty
|
|
95
105
|
* `errors()` also counts as invalid.
|
|
96
106
|
*/
|
|
97
107
|
invalid?: () => boolean;
|
|
108
|
+
/** Whether async validation is pending. Pending validity remains neutral, never falsely valid. */
|
|
109
|
+
pending?: () => boolean;
|
|
98
110
|
disabled?: () => boolean;
|
|
99
111
|
required?: () => boolean;
|
|
100
112
|
dirty?: () => boolean;
|
|
@@ -108,7 +120,7 @@ interface RdxFieldState {
|
|
|
108
120
|
* any enclosing Form's server messages. Uses `core`'s framework-free shim type so the seam stays free of
|
|
109
121
|
* `@angular/forms/signals` (ADR 0004 amendment).
|
|
110
122
|
*/
|
|
111
|
-
errors?: () => RdxValidationError[];
|
|
123
|
+
errors?: () => readonly RdxValidationError[];
|
|
112
124
|
}
|
|
113
125
|
interface RdxFieldRootContext {
|
|
114
126
|
controlId: Signal<string>;
|
|
@@ -116,6 +128,8 @@ interface RdxFieldRootContext {
|
|
|
116
128
|
descriptionIds: Signal<string[]>;
|
|
117
129
|
errorIds: Signal<string[]>;
|
|
118
130
|
messages: Signal<string[]>;
|
|
131
|
+
/** Whether the currently displayed client errors contain this validation kind. */
|
|
132
|
+
matchesError: (kind: string) => boolean;
|
|
119
133
|
notifyEdited: () => void;
|
|
120
134
|
/** Tri-state *displayed* validity (`true` valid / `false` invalid / `null` neutral), gated by the
|
|
121
135
|
* field's `validationMode`. The source for `data-valid` / `data-invalid` on the field and its controls. */
|
|
@@ -229,6 +243,8 @@ declare class RdxFieldRoot {
|
|
|
229
243
|
private readonly stateProvider;
|
|
230
244
|
/** Whether an external adapter currently owns field state. */
|
|
231
245
|
readonly hasStateProvider: Signal<boolean>;
|
|
246
|
+
/** Explicit field name wins; an adapter may infer one from its form-control binding. */
|
|
247
|
+
readonly effectiveName: Signal<string | undefined>;
|
|
232
248
|
/** Error content from a registered state provider (e.g. a Signal Forms adapter). */
|
|
233
249
|
private readonly providerErrors;
|
|
234
250
|
/** **Client** validation errors routed by a form-level provider (`rdxSignalForm`) — gated by `validationMode`. */
|
|
@@ -246,6 +262,8 @@ declare class RdxFieldRoot {
|
|
|
246
262
|
* field state), so deduping renders it once while still surfacing distinct messages from each source.
|
|
247
263
|
*/
|
|
248
264
|
readonly messages: Signal<string[]>;
|
|
265
|
+
/** Whether a client validation error of `kind` is currently revealed by the field. */
|
|
266
|
+
matchesError(kind: string): boolean;
|
|
249
267
|
/** Effective validation-display mode: this field's override → the enclosing Form's → the default. */
|
|
250
268
|
readonly effectiveValidationMode: Signal<RdxValidationMode>;
|
|
251
269
|
/** Whether client-side validity is revealed yet, per {@link effectiveValidationMode} + interaction. */
|
|
@@ -276,6 +294,7 @@ declare class RdxFieldRoot {
|
|
|
276
294
|
* the provider/input `invalid`.
|
|
277
295
|
*/
|
|
278
296
|
readonly actualInvalidState: Signal<boolean>;
|
|
297
|
+
readonly pendingState: Signal<boolean>;
|
|
279
298
|
readonly disabledState: Signal<boolean>;
|
|
280
299
|
readonly requiredState: Signal<boolean>;
|
|
281
300
|
readonly dirtyState: Signal<boolean>;
|
|
@@ -310,8 +329,8 @@ declare class RdxFieldRoot {
|
|
|
310
329
|
clearStateProvider(provider: RdxFieldState | null, previous: RdxFieldState | null): void;
|
|
311
330
|
/**
|
|
312
331
|
* Prefer the registered provider's value for `key` when it exposes one,
|
|
313
|
-
* otherwise fall back to the root inputs / DOM-derived signals. `
|
|
314
|
-
*
|
|
332
|
+
* otherwise fall back to the root inputs / DOM-derived signals. `name` and `errors` are resolved
|
|
333
|
+
* separately, so they're excluded from this boolean key.
|
|
315
334
|
*/
|
|
316
335
|
private resolve;
|
|
317
336
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxFieldRoot, never>;
|
|
@@ -369,5 +388,33 @@ declare class RdxFieldLabel {
|
|
|
369
388
|
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxFieldLabel, "[rdxFieldLabel]", ["rdxFieldLabel"], { "id": { "alias": "id"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
370
389
|
}
|
|
371
390
|
|
|
372
|
-
|
|
391
|
+
/**
|
|
392
|
+
* Bridges a same-host Reactive Forms or template-driven `NgControl` into an enclosing `rdxFieldRoot`.
|
|
393
|
+
* Place it next to `formControl`, `formControlName`, or `ngModel`; Angular remains the source of value,
|
|
394
|
+
* validation, and interaction state while Field owns when that state is displayed.
|
|
395
|
+
*
|
|
396
|
+
* ```html
|
|
397
|
+
* <div rdxFieldRoot>
|
|
398
|
+
* <label rdxFieldLabel>Email</label>
|
|
399
|
+
* <input formControlName="email" rdxFieldControl rdxNgControlField />
|
|
400
|
+
* <p match="required" rdxFieldError>Email is required.</p>
|
|
401
|
+
* </div>
|
|
402
|
+
* ```
|
|
403
|
+
*
|
|
404
|
+
* The adapter also infers the Field name from `formControlName` / `ngModel` for Form-level server-error
|
|
405
|
+
* routing. An explicit `name` on `rdxFieldRoot` takes precedence (useful for nested or remapped keys).
|
|
406
|
+
*
|
|
407
|
+
* @group Components
|
|
408
|
+
*/
|
|
409
|
+
declare class RdxNgControlField {
|
|
410
|
+
private readonly ngControlState;
|
|
411
|
+
private readonly fieldContext;
|
|
412
|
+
/** Normalized Angular validation errors (`{ kind, message? }[]`). */
|
|
413
|
+
readonly validationErrors: _angular_core.Signal<readonly _radix_ng_primitives_core.RdxValidationError[]>;
|
|
414
|
+
constructor();
|
|
415
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxNgControlField, never>;
|
|
416
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxNgControlField, "[formControl][rdxNgControlField], [formControlName][rdxNgControlField], [ngModel][rdxNgControlField]", ["rdxNgControlField"], {}, {}, never, never, true, never>;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
export { RdxFieldControl, RdxFieldDescription, RdxFieldError, RdxFieldItem, RdxFieldLabel, RdxFieldRoot, RdxNgControlField, injectFieldRootContext, provideFieldRootContext };
|
|
373
420
|
export type { RdxFieldRootContext, RdxFieldState };
|
|
@@ -162,6 +162,13 @@ declare class RdxFloatingFocusManager {
|
|
|
162
162
|
* - an element (direct or from a callback) → that element (returned **explicitly**, bypassing the
|
|
163
163
|
* "focus moved elsewhere" guard).
|
|
164
164
|
*/
|
|
165
|
+
/**
|
|
166
|
+
* Public view of {@link resolveReturnFocusTarget} for a **keep-mounted** primitive to apply
|
|
167
|
+
* return-focus on *close* — the composed scope's unmount-driven return never runs while the popup
|
|
168
|
+
* stays in the DOM. Returns an explicit element, `false` (suppress), or `undefined` (default →
|
|
169
|
+
* caller restores the previously-focused element, e.g. the trigger).
|
|
170
|
+
*/
|
|
171
|
+
resolveReturnTarget(): HTMLElement | false | undefined;
|
|
165
172
|
private resolveReturnFocusTarget;
|
|
166
173
|
/**
|
|
167
174
|
* Base UI's `defaultInitialFocus`: on a **touch** open, focus the popup itself instead of its first
|