@radix-ng/primitives 1.0.6 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/aspect-ratio/README.md +1 -1
  2. package/fesm2022/radix-ng-primitives-accordion.mjs +6 -1
  3. package/fesm2022/radix-ng-primitives-accordion.mjs.map +1 -1
  4. package/fesm2022/radix-ng-primitives-aspect-ratio.mjs +9 -34
  5. package/fesm2022/radix-ng-primitives-aspect-ratio.mjs.map +1 -1
  6. package/fesm2022/radix-ng-primitives-autocomplete.mjs +43 -9
  7. package/fesm2022/radix-ng-primitives-autocomplete.mjs.map +1 -1
  8. package/fesm2022/radix-ng-primitives-avatar.mjs +69 -18
  9. package/fesm2022/radix-ng-primitives-avatar.mjs.map +1 -1
  10. package/fesm2022/radix-ng-primitives-checkbox.mjs +93 -16
  11. package/fesm2022/radix-ng-primitives-checkbox.mjs.map +1 -1
  12. package/fesm2022/radix-ng-primitives-collapsible.mjs +4 -3
  13. package/fesm2022/radix-ng-primitives-collapsible.mjs.map +1 -1
  14. package/fesm2022/radix-ng-primitives-combobox.mjs +43 -9
  15. package/fesm2022/radix-ng-primitives-combobox.mjs.map +1 -1
  16. package/fesm2022/radix-ng-primitives-core.mjs +208 -2
  17. package/fesm2022/radix-ng-primitives-core.mjs.map +1 -1
  18. package/fesm2022/radix-ng-primitives-date-field.mjs +50 -9
  19. package/fesm2022/radix-ng-primitives-date-field.mjs.map +1 -1
  20. package/fesm2022/radix-ng-primitives-editable.mjs +31 -5
  21. package/fesm2022/radix-ng-primitives-editable.mjs.map +1 -1
  22. package/fesm2022/radix-ng-primitives-field.mjs +276 -58
  23. package/fesm2022/radix-ng-primitives-field.mjs.map +1 -1
  24. package/fesm2022/radix-ng-primitives-form.mjs +111 -27
  25. package/fesm2022/radix-ng-primitives-form.mjs.map +1 -1
  26. package/fesm2022/radix-ng-primitives-input.mjs +16 -6
  27. package/fesm2022/radix-ng-primitives-input.mjs.map +1 -1
  28. package/fesm2022/radix-ng-primitives-label.mjs +5 -4
  29. package/fesm2022/radix-ng-primitives-label.mjs.map +1 -1
  30. package/fesm2022/radix-ng-primitives-number-field.mjs +39 -10
  31. package/fesm2022/radix-ng-primitives-number-field.mjs.map +1 -1
  32. package/fesm2022/radix-ng-primitives-progress.mjs +37 -22
  33. package/fesm2022/radix-ng-primitives-progress.mjs.map +1 -1
  34. package/fesm2022/radix-ng-primitives-radio.mjs +18 -9
  35. package/fesm2022/radix-ng-primitives-radio.mjs.map +1 -1
  36. package/fesm2022/radix-ng-primitives-scroll-area.mjs +4 -4
  37. package/fesm2022/radix-ng-primitives-scroll-area.mjs.map +1 -1
  38. package/fesm2022/radix-ng-primitives-select.mjs +26 -8
  39. package/fesm2022/radix-ng-primitives-select.mjs.map +1 -1
  40. package/fesm2022/radix-ng-primitives-separator.mjs +7 -13
  41. package/fesm2022/radix-ng-primitives-separator.mjs.map +1 -1
  42. package/fesm2022/radix-ng-primitives-signal-forms.mjs +184 -0
  43. package/fesm2022/radix-ng-primitives-signal-forms.mjs.map +1 -0
  44. package/fesm2022/radix-ng-primitives-slider.mjs +25 -10
  45. package/fesm2022/radix-ng-primitives-slider.mjs.map +1 -1
  46. package/fesm2022/radix-ng-primitives-switch.mjs +32 -8
  47. package/fesm2022/radix-ng-primitives-switch.mjs.map +1 -1
  48. package/fesm2022/radix-ng-primitives-tabs.mjs +4 -4
  49. package/fesm2022/radix-ng-primitives-tabs.mjs.map +1 -1
  50. package/fesm2022/radix-ng-primitives-time-field.mjs +49 -9
  51. package/fesm2022/radix-ng-primitives-time-field.mjs.map +1 -1
  52. package/fesm2022/radix-ng-primitives-toggle-group.mjs +33 -16
  53. package/fesm2022/radix-ng-primitives-toggle-group.mjs.map +1 -1
  54. package/fesm2022/radix-ng-primitives-toggle.mjs +24 -29
  55. package/fesm2022/radix-ng-primitives-toggle.mjs.map +1 -1
  56. package/fesm2022/radix-ng-primitives-toolbar.mjs +15 -2
  57. package/fesm2022/radix-ng-primitives-toolbar.mjs.map +1 -1
  58. package/package.json +11 -1
  59. package/types/radix-ng-primitives-accordion.d.ts +1 -0
  60. package/types/radix-ng-primitives-aspect-ratio.d.ts +10 -23
  61. package/types/radix-ng-primitives-autocomplete.d.ts +21 -2
  62. package/types/radix-ng-primitives-avatar.d.ts +51 -25
  63. package/types/radix-ng-primitives-checkbox.d.ts +78 -101
  64. package/types/radix-ng-primitives-combobox.d.ts +51 -2
  65. package/types/radix-ng-primitives-core.d.ts +206 -3
  66. package/types/radix-ng-primitives-date-field.d.ts +27 -2
  67. package/types/radix-ng-primitives-editable.d.ts +15 -2
  68. package/types/radix-ng-primitives-field.d.ts +165 -236
  69. package/types/radix-ng-primitives-form.d.ts +122 -37
  70. package/types/radix-ng-primitives-input.d.ts +8 -1
  71. package/types/radix-ng-primitives-label.d.ts +3 -2
  72. package/types/radix-ng-primitives-number-field.d.ts +15 -4
  73. package/types/radix-ng-primitives-progress.d.ts +59 -121
  74. package/types/radix-ng-primitives-radio.d.ts +7 -3
  75. package/types/radix-ng-primitives-select.d.ts +11 -3
  76. package/types/radix-ng-primitives-separator.d.ts +0 -7
  77. package/types/radix-ng-primitives-signal-forms.d.ts +97 -0
  78. package/types/radix-ng-primitives-slider.d.ts +9 -7
  79. package/types/radix-ng-primitives-switch.d.ts +15 -2
  80. package/types/radix-ng-primitives-time-field.d.ts +26 -2
  81. package/types/radix-ng-primitives-toggle-group.d.ts +13 -7
  82. package/types/radix-ng-primitives-toggle.d.ts +8 -8
  83. package/types/radix-ng-primitives-toolbar.d.ts +2 -0
@@ -1,7 +1,7 @@
1
1
  import * as _angular_core from '@angular/core';
2
2
  import { Signal, ElementRef, InjectionToken, OutputRef, WritableSignal } from '@angular/core';
3
3
  import * as _radix_ng_primitives_core from '@radix-ng/primitives/core';
4
- import { AcceptableValue, RdxCancelableChangeEventDetails, RdxFloatingRootContext, Direction, ItemValueComparator, RdxTransitionStatus } from '@radix-ng/primitives/core';
4
+ import { AcceptableValue, RdxCancelableChangeEventDetails, RdxFormUiControlBase, RdxFormValueControl, RdxFloatingRootContext, Direction, ItemValueComparator, RdxTransitionStatus, RdxFormUiStateContext } from '@radix-ng/primitives/core';
5
5
  import * as _radix_ng_primitives_select from '@radix-ng/primitives/select';
6
6
  import * as i1 from '@radix-ng/primitives/composite';
7
7
  import { RdxCompositeItemRegistration } from '@radix-ng/primitives/composite';
@@ -330,7 +330,7 @@ interface RdxSelectValueChangeEvent {
330
330
  value: AcceptableValue | AcceptableValue[] | undefined;
331
331
  eventDetails: RdxSelectValueChangeEventDetails;
332
332
  }
333
- interface RdxSelectRootContext {
333
+ interface RdxSelectRootContext extends RdxFormUiStateContext {
334
334
  triggerElement: WritableSignal<HTMLElement | null>;
335
335
  valueElement: WritableSignal<HTMLElement | null>;
336
336
  triggerPointerDownPosRef: WritableSignal<{
@@ -365,7 +365,7 @@ interface RdxSelectRootContext {
365
365
  }
366
366
  declare const injectSelectRootContext: _radix_ng_primitives_core.InjectContext<RdxSelectRootContext>;
367
367
  declare const provideSelectRootContext: (useFactory: () => RdxSelectRootContext) => _angular_core.Provider;
368
- declare class RdxSelectRoot {
368
+ declare class RdxSelectRoot extends RdxFormUiControlBase implements RdxFormValueControl<AcceptableValue | AcceptableValue[] | undefined> {
369
369
  readonly contentId: string;
370
370
  readonly open: _angular_core.ModelSignal<boolean>;
371
371
  /** Whether the current open was initiated by **touch** (ADR 0016 §3 — gates the anchored scroll lock). */
@@ -475,8 +475,16 @@ declare class RdxSelectTrigger {
475
475
  readonly isDisabled: _angular_core.Signal<boolean>;
476
476
  protected readonly triggerInteraction: i2.RdxTriggerInteraction;
477
477
  protected readonly invalidState: _angular_core.Signal<boolean>;
478
+ /**
479
+ * Tri-state *displayed* validity: when inside a `rdxFieldRoot` the field's gated `validState` is the
480
+ * single source (so the field's `validationMode` keeps the trigger neutral until revealed), otherwise
481
+ * the trigger's own binary invalidity.
482
+ */
483
+ protected readonly displayValid: _angular_core.Signal<boolean | null>;
478
484
  protected readonly requiredState: _angular_core.Signal<boolean>;
479
485
  protected readonly readOnlyState: _angular_core.Signal<boolean>;
486
+ protected readonly touchedState: _angular_core.Signal<boolean>;
487
+ protected readonly dirtyState: _angular_core.Signal<boolean>;
480
488
  protected readonly filledState: _angular_core.Signal<boolean>;
481
489
  protected readonly focusedState: _angular_core.Signal<boolean>;
482
490
  protected readonly describedBy: _angular_core.Signal<string | undefined>;
@@ -22,13 +22,6 @@ declare class RdxSeparatorRootDirective {
22
22
  */
23
23
  readonly orientation: _angular_core.InputSignal<Orientation>;
24
24
  protected readonly orientationState: _angular_core.WritableSignal<Orientation>;
25
- /**
26
- * Computes the `aria-orientation` attribute. It is set to "vertical" only when
27
- * the separator orientation is vertical. Horizontal is the implicit ARIA default.
28
- *
29
- * @ignore
30
- */
31
- protected readonly computedAriaOrientation: _angular_core.Signal<"vertical" | undefined>;
32
25
  updateOrientation(value: Orientation): void;
33
26
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxSeparatorRootDirective, never>;
34
27
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxSeparatorRootDirective, "[rdxSeparatorRoot]", never, { "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
@@ -0,0 +1,97 @@
1
+ import * as i0 from '@angular/core';
2
+ import { FieldTree } from '@angular/forms/signals';
3
+
4
+ /**
5
+ * Bridges an Angular **Signal Forms** field into an enclosing `rdxFieldRoot` — with **no duplicate
6
+ * binding**. Place it on the control that already carries `[formField]`; it reads the bound field's
7
+ * state from that directive, so the field expression is written exactly once:
8
+ *
9
+ * ```html
10
+ * <div rdxFieldRoot>
11
+ * <label rdxFieldLabel>Email</label>
12
+ * <input rdxInput [formField]="loginForm.email" rdxSignalField />
13
+ * <p rdxFieldError>Email is required.</p>
14
+ * </div>
15
+ * ```
16
+ *
17
+ * It owns no model and runs no validation — Signal Forms remains the source of truth. It only registers
18
+ * an {@link RdxFieldState} provider on the ancestor Field context so the field's `invalid` / `disabled` /
19
+ * `required` / `dirty` / `touched` data-attributes and the error *content* (`rdxFieldError.messages()`)
20
+ * read authoritative Signal Forms state. `filled` / `focused` stay on Field's DOM heuristic (partial
21
+ * ownership — the seam supports it).
22
+ *
23
+ * It reports the **actual** Signal Forms state only; the `Field` decides *when* to display it from its
24
+ * `validationMode` (default `'onBlur'` — neutral until the field is touched or the form submitted). So an
25
+ * empty required field is neutral on load with no manual `[invalid]`/`[touched]` wiring, and a pristine
26
+ * submit reveals the errors (the `Form` records the submit attempt before checking validity and blocks).
27
+ *
28
+ * See ADR 0018.
29
+ *
30
+ * @group Components
31
+ */
32
+ declare class RdxSignalField {
33
+ /** The co-located `[formField]` directive — the single source of the bound field's state. */
34
+ private readonly formField;
35
+ private readonly fieldContext;
36
+ constructor();
37
+ /** Current Signal Forms field state, read from the co-located `[formField]` directive. */
38
+ private state;
39
+ static ɵfac: i0.ɵɵFactoryDeclaration<RdxSignalField, never>;
40
+ static ɵdir: i0.ɵɵDirectiveDeclaration<RdxSignalField, "[formField][rdxSignalField]", ["rdxSignalField"], {}, {}, never, never, true, never>;
41
+ }
42
+
43
+ /**
44
+ * Bridges an Angular **Signal Forms** form into an enclosing `form[rdxFormRoot]`.
45
+ *
46
+ * ```html
47
+ * <form rdxFormRoot [rdxSignalForm]="loginForm">
48
+ * <!-- fields bound with [formField] (+ rdxSignalField) -->
49
+ * </form>
50
+ * ```
51
+ *
52
+ * Registers an {@link RdxFormState} provider so the Form's aggregate `data-invalid` / `data-dirty` /
53
+ * `data-touched` / `data-submitting` attributes and the submit guard read authoritative Signal Forms
54
+ * state. This adapter owns only client-side state and `name`-routing; server errors stay a separate
55
+ * eager channel applied through `rdxFormRoot[errors]`, and Signal Forms' own `submit()` owns the
56
+ * submit lifecycle.
57
+ *
58
+ * `errorsFor(name)` routes a field's errors to a `rdxFieldRoot` by its `name`, walking the `FieldTree`
59
+ * so dotted paths into nested object/array fields resolve too (`address.street`, `items.0.name`). A
60
+ * field can surface messages from the form alone — no per-field `rdxSignalField` needed for errors.
61
+ * These are the **two modes** (per-field adapter vs form-level name routing) — prefer one per field; if
62
+ * a field carries both, `rdxFieldError.messages()` deduplicates by text so the shared message is not
63
+ * shown twice.
64
+ *
65
+ * See ADR 0018.
66
+ *
67
+ * @group Components
68
+ */
69
+ declare class RdxSignalForm {
70
+ /** The Signal Forms root field (from `form(...)`) whose aggregate state drives the enclosing Form. */
71
+ readonly form: i0.InputSignal<FieldTree<unknown>>;
72
+ private readonly formContext;
73
+ constructor();
74
+ /**
75
+ * Messages for the field at the dotted `name` path (`message ?? kind` per error). Walks the
76
+ * `FieldTree` so nested object/array fields resolve too — e.g. `address.street`, `items.0.name`.
77
+ */
78
+ private errorsFor;
79
+ /**
80
+ * The Signal Forms field *state* at the dotted `name` path, or `null` if it doesn't resolve. Walks the
81
+ * `FieldTree` so nested object/array fields work (`address.street`, `items.0.name`).
82
+ */
83
+ private fieldState;
84
+ /** The current Signal Forms root field state (a `FieldTree` is callable). */
85
+ private state;
86
+ static ɵfac: i0.ɵɵFactoryDeclaration<RdxSignalForm, never>;
87
+ static ɵdir: i0.ɵɵDirectiveDeclaration<RdxSignalForm, "form[rdxFormRoot][rdxSignalForm]", ["rdxSignalForm"], { "form": { "alias": "rdxSignalForm"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
88
+ }
89
+
90
+ declare const _importsSignalForms: (typeof RdxSignalField | typeof RdxSignalForm)[];
91
+ declare class RdxSignalFormsModule {
92
+ static ɵfac: i0.ɵɵFactoryDeclaration<RdxSignalFormsModule, never>;
93
+ static ɵmod: i0.ɵɵNgModuleDeclaration<RdxSignalFormsModule, never, [typeof RdxSignalField, typeof RdxSignalForm], [typeof RdxSignalField, typeof RdxSignalForm]>;
94
+ static ɵinj: i0.ɵɵInjectorDeclaration<RdxSignalFormsModule>;
95
+ }
96
+
97
+ export { RdxSignalField, RdxSignalForm, RdxSignalFormsModule, _importsSignalForms };
@@ -1,7 +1,7 @@
1
1
  import * as _angular_core from '@angular/core';
2
2
  import { Signal } from '@angular/core';
3
- import * as _radix_ng_primitives_core from '@radix-ng/primitives/core';
4
- import { RdxControlValueAccessor, NumberInput, BooleanInput, RdxCancelableChangeEventDetails } from '@radix-ng/primitives/core';
3
+ import * as i2 from '@radix-ng/primitives/core';
4
+ import { RdxFormUiControlBase, RdxControlValueAccessor, NumberInput, BooleanInput, RdxCancelableChangeEventDetails, RdxFormUiTouchTarget } from '@radix-ng/primitives/core';
5
5
  export { clamp } from '@radix-ng/primitives/core';
6
6
  import * as i1 from '@radix-ng/primitives/composite';
7
7
  import * as _radix_ng_primitives_slider from '@radix-ng/primitives/slider';
@@ -131,7 +131,7 @@ interface RdxSliderThumbMetadata {
131
131
  *
132
132
  * @see https://base-ui.com/react/components/slider
133
133
  */
134
- declare class RdxSliderRoot {
134
+ declare class RdxSliderRoot extends RdxFormUiControlBase {
135
135
  /** @ignore */
136
136
  protected readonly cva: RdxControlValueAccessor<SliderValue>;
137
137
  private readonly document;
@@ -172,7 +172,7 @@ declare class RdxSliderRoot {
172
172
  * @default 'ltr'
173
173
  */
174
174
  readonly dirInput: _angular_core.InputSignal<"ltr" | "rtl" | undefined>;
175
- readonly dir: Signal<_radix_ng_primitives_core.Direction>;
175
+ readonly dir: Signal<i2.Direction>;
176
176
  /**
177
177
  * How thumbs behave when they meet in a range slider.
178
178
  * @default 'push'
@@ -272,7 +272,9 @@ declare class RdxSliderRoot {
272
272
  handleInputChange(valueInput: number, index: number, reason?: RdxSliderValueChangeReason, event?: Event): void;
273
273
  /** @ignore Emits the committed value at the end of a pointer drag. */
274
274
  commitValue(event?: Event, reason?: RdxSliderValueCommitReason): void;
275
- /** @ignore */
275
+ /** @ignore Bridge the CVA into `markAsTouched` (dual). */
276
+ protected formUiTouchTarget(): RdxFormUiTouchTarget;
277
+ /** @ignore Mark touched: CVA (Reactive/template) + `touched` model + `touch` (Signal Forms). */
276
278
  markAsTouched(): void;
277
279
  /** @ignore */
278
280
  setDragging(dragging: boolean): void;
@@ -281,7 +283,7 @@ declare class RdxSliderRoot {
281
283
  /** @ignore */
282
284
  getOwnerWindow(): Window | undefined;
283
285
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxSliderRoot, never>;
284
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxSliderRoot, "div[rdxSliderRoot]", ["rdxSliderRoot"], { "id": { "alias": "id"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "largeStep": { "alias": "largeStep"; "required": false; "isSignal": true; }; "minStepsBetweenValues": { "alias": "minStepsBetweenValues"; "required": false; "isSignal": true; }; "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "dirInput": { "alias": "dir"; "required": false; "isSignal": true; }; "thumbCollisionBehavior": { "alias": "thumbCollisionBehavior"; "required": false; "isSignal": true; }; "thumbAlignment": { "alias": "thumbAlignment"; "required": false; "isSignal": true; }; "format": { "alias": "format"; "required": false; "isSignal": true; }; "locale": { "alias": "locale"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "form": { "alias": "form"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "defaultValue": { "alias": "defaultValue"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "ariaLabelledBy": { "alias": "aria-labelledby"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "onValueChange": "onValueChange"; "onValueCommitted": "onValueCommitted"; }, never, never, true, [{ directive: typeof i1.RdxCompositeList; inputs: {}; outputs: {}; }, { directive: typeof _radix_ng_primitives_core.RdxControlValueAccessor; inputs: { "value": "value"; "disabled": "disabled"; }; outputs: {}; }]>;
286
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxSliderRoot, "div[rdxSliderRoot]", ["rdxSliderRoot"], { "id": { "alias": "id"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "largeStep": { "alias": "largeStep"; "required": false; "isSignal": true; }; "minStepsBetweenValues": { "alias": "minStepsBetweenValues"; "required": false; "isSignal": true; }; "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "dirInput": { "alias": "dir"; "required": false; "isSignal": true; }; "thumbCollisionBehavior": { "alias": "thumbCollisionBehavior"; "required": false; "isSignal": true; }; "thumbAlignment": { "alias": "thumbAlignment"; "required": false; "isSignal": true; }; "format": { "alias": "format"; "required": false; "isSignal": true; }; "locale": { "alias": "locale"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "form": { "alias": "form"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "defaultValue": { "alias": "defaultValue"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "ariaLabelledBy": { "alias": "aria-labelledby"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "onValueChange": "onValueChange"; "onValueCommitted": "onValueCommitted"; }, never, never, true, [{ directive: typeof i1.RdxCompositeList; inputs: {}; outputs: {}; }, { directive: typeof i2.RdxFormUiStateHost; inputs: {}; outputs: {}; }, { directive: typeof i2.RdxControlValueAccessor; inputs: { "value": "value"; "disabled": "disabled"; }; outputs: {}; }]>;
285
287
  }
286
288
 
287
289
  /**
@@ -431,7 +433,7 @@ declare class RdxSliderValue {
431
433
  *
432
434
  * @see https://base-ui.com/react/components/slider
433
435
  */
434
- declare const injectSliderRootContext: _radix_ng_primitives_core.InjectContext<RdxSliderRoot>;
436
+ declare const injectSliderRootContext: i2.InjectContext<RdxSliderRoot>;
435
437
  declare const provideSliderRootContext: (useFactory: () => RdxSliderRoot) => _angular_core.Provider;
436
438
 
437
439
  declare class RdxSliderModule {
@@ -2,7 +2,7 @@ import * as _radix_ng_primitives_switch from '@radix-ng/primitives/switch';
2
2
  import * as _angular_core from '@angular/core';
3
3
  import { Signal } from '@angular/core';
4
4
  import * as i1 from '@radix-ng/primitives/core';
5
- import { RdxCancelableChangeEventDetails, RdxFormCheckboxControl, RdxControlValueAccessor, BooleanInput } from '@radix-ng/primitives/core';
5
+ import { RdxCancelableChangeEventDetails, RdxFormUiControlBase, RdxFormCheckboxControl, RdxControlValueAccessor, BooleanInput, RdxFormUiTouchTarget } from '@radix-ng/primitives/core';
6
6
 
7
7
  /**
8
8
  * The hidden native checkbox that mirrors the switch state for form submission and screen readers.
@@ -26,7 +26,7 @@ interface RdxSwitchCheckedChangeEvent {
26
26
  *
27
27
  * @see https://base-ui.com/react/components/switch
28
28
  */
29
- declare class RdxSwitchRoot implements RdxFormCheckboxControl {
29
+ declare class RdxSwitchRoot extends RdxFormUiControlBase implements RdxFormCheckboxControl {
30
30
  /** @ignore */
31
31
  protected readonly cva: RdxControlValueAccessor<boolean | undefined>;
32
32
  readonly id: _angular_core.InputSignal<string>;
@@ -79,7 +79,20 @@ declare class RdxSwitchRoot implements RdxFormCheckboxControl {
79
79
  readonly checkedState: _angular_core.Signal<boolean>;
80
80
  /** @ignore */
81
81
  protected readonly isDisabled: _angular_core.Signal<boolean>;
82
+ /** @ignore */
83
+ readonly invalidState: _angular_core.Signal<boolean>;
84
+ /** @ignore */
85
+ readonly touchedState: _angular_core.Signal<boolean>;
86
+ /** @ignore */
87
+ readonly dirtyState: _angular_core.Signal<boolean>;
82
88
  constructor();
89
+ /** @ignore Bridge the CVA into `markAsTouched` (dual). */
90
+ protected formUiTouchTarget(): RdxFormUiTouchTarget;
91
+ /**
92
+ * Mark the switch touched — CVA for Reactive forms, plus the `touched` model + `touch` output for
93
+ * Signal Forms. Called on blur of the root button or the hidden input.
94
+ */
95
+ markAsTouched(): void;
83
96
  /** @ignore Toggles the checked state unless disabled or read-only. */
84
97
  toggle(event?: Event): void;
85
98
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxSwitchRoot, never>;
@@ -1,10 +1,10 @@
1
1
  import * as _angular_core from '@angular/core';
2
2
  import { Signal, WritableSignal, InjectionToken, InputSignal, ModelSignal } from '@angular/core';
3
3
  import * as _radix_ng_primitives_core from '@radix-ng/primitives/core';
4
- import { TimeValue, HourCycle, Granularity, Direction, BooleanInput, DateStep, Formatter, SegmentValueObj, SegmentPart } from '@radix-ng/primitives/core';
4
+ import { RdxFormUiControlBase, RdxFormValueControl, TimeValue, HourCycle, Granularity, Direction, BooleanInput, DateStep, Formatter, SegmentValueObj, SegmentPart } from '@radix-ng/primitives/core';
5
5
  import * as _internationalized_date from '@internationalized/date';
6
6
 
7
- declare class RdxTimeFieldRootDirective {
7
+ declare class RdxTimeFieldRootDirective extends RdxFormUiControlBase implements RdxFormValueControl<TimeValue | undefined> {
8
8
  /**
9
9
  * The controlled checked state of the calendar.
10
10
  */
@@ -96,6 +96,24 @@ declare class RdxTimeFieldRootDirective {
96
96
  * @ignore
97
97
  */
98
98
  readonly isInvalid: Signal<boolean>;
99
+ /**
100
+ * @ignore Effective invalid: the built-in range check OR the form-driven `invalid` / `errors`
101
+ * (Signal Forms). Reflected on the root and segments.
102
+ */
103
+ readonly invalidState: Signal<boolean>;
104
+ /**
105
+ * @ignore Tri-state display validity: the enclosing Field's gated state when inside a `rdxFieldRoot`,
106
+ * else the time-field's own (parse + form) invalidity. Overrides the base default (`formUi` only).
107
+ */
108
+ readonly displayValid: Signal<boolean | null>;
109
+ /** @ignore */
110
+ readonly touchedState: Signal<boolean>;
111
+ /** @ignore */
112
+ readonly dirtyState: Signal<boolean>;
113
+ /** @ignore Whether the user has focused a segment — gates dirty tracking so a form/initial seed of `value` doesn't mark dirty. */
114
+ private readonly userInteracted;
115
+ /** @ignore Mark the field touched (model + `touch` output) for Signal Forms. Called on segment blur. */
116
+ markAsTouched(): void;
99
117
  /**
100
118
  * @ignore
101
119
  */
@@ -168,6 +186,8 @@ declare class RdxTimeFieldInputDirective {
168
186
  * @ignore
169
187
  */
170
188
  readonly isInvalid: _angular_core.Signal<boolean>;
189
+ /** @ignore Tri-state display validity from the root (gated by an enclosing Field). */
190
+ readonly displayValid: _angular_core.Signal<boolean | null>;
171
191
  /**
172
192
  * @ignore
173
193
  */
@@ -204,6 +224,10 @@ interface TimeFieldContextToken {
204
224
  value: ModelSignal<TimeValue | undefined>;
205
225
  placeholder: ModelSignal<TimeValue>;
206
226
  isInvalid: Signal<boolean>;
227
+ /** Effective invalid: the built-in range check OR the form-driven invalid state. */
228
+ invalidState: Signal<boolean>;
229
+ /** Tri-state displayed validity (`true`/`false`/`null`): the field's gated state inside a Field, else own. */
230
+ displayValid: Signal<boolean | null>;
207
231
  disabled: InputSignal<boolean>;
208
232
  readonly: InputSignal<boolean>;
209
233
  formatter: Signal<Formatter>;
@@ -1,7 +1,7 @@
1
1
  import * as _angular_core from '@angular/core';
2
2
  import { Signal } from '@angular/core';
3
3
  import * as _radix_ng_primitives_core from '@radix-ng/primitives/core';
4
- import { DataOrientation, RdxCancelableChangeEventDetails, BooleanInput, Direction } from '@radix-ng/primitives/core';
4
+ import { DataOrientation, RdxCancelableChangeEventDetails, RdxFormUiControlBase, RdxFormValueControl, BooleanInput, RdxFormUiTouchTarget, Direction } from '@radix-ng/primitives/core';
5
5
  import { ControlValueAccessor } from '@angular/forms';
6
6
  import * as i1 from '@radix-ng/primitives/composite';
7
7
 
@@ -18,8 +18,12 @@ interface RdxToggleGroupContext {
18
18
  readonly orientation: Signal<DataOrientation>;
19
19
  /** Whether the group value was initialized by `value` or `defaultValue`. */
20
20
  readonly isValueInitialized: Signal<boolean>;
21
- /** Toggle the pressed state of `value` within the group. */
22
- toggle(value: string, event?: Event, eventDetails?: RdxCancelableChangeEventDetails<RdxToggleGroupContextChangeReason>): void;
21
+ /**
22
+ * Set the pressed state of `value` within the group. The item computes the next pressed boolean
23
+ * (Base UI parity — the item is the source of truth), so the group applies it rather than
24
+ * re-deriving the toggle from its current value set.
25
+ */
26
+ toggle(value: string, nextPressed: boolean, event?: Event, eventDetails?: RdxCancelableChangeEventDetails<RdxToggleGroupContextChangeReason>): void;
23
27
  }
24
28
  declare const injectToggleGroupContext: _radix_ng_primitives_core.InjectContext<RdxToggleGroupContext>;
25
29
  declare const provideToggleGroupContext: (useFactory: () => RdxToggleGroupContext) => _angular_core.Provider;
@@ -37,7 +41,7 @@ declare function toggleGroupContext(instance: RdxToggleGroupBase): RdxToggleGrou
37
41
  * ({@link RdxToggleGroup}) or omit it when an ancestor already owns focus, e.g. a toolbar
38
42
  * ({@link RdxToggleGroupWithoutFocus}).
39
43
  */
40
- declare abstract class RdxToggleGroupBase implements ControlValueAccessor {
44
+ declare abstract class RdxToggleGroupBase extends RdxFormUiControlBase implements ControlValueAccessor, RdxFormValueControl<string[] | undefined> {
41
45
  /**
42
46
  * The pressed values. Always an array — a single value is `[value]`. Use with `(onValueChange)`
43
47
  * for controlled state.
@@ -75,10 +79,12 @@ declare abstract class RdxToggleGroupBase implements ControlValueAccessor {
75
79
  private onChange?;
76
80
  protected onTouched?: () => void;
77
81
  constructor();
82
+ /** @ignore Bridge the CVA `onTouched` so `markAsTouched()` also notifies Reactive/template forms. */
83
+ protected formUiTouchTarget(): RdxFormUiTouchTarget;
78
84
  /** @ignore Extra disabled state inherited from composite parents such as Toolbar. */
79
85
  protected isExternallyDisabled(): boolean;
80
86
  /** @ignore */
81
- toggle(value: string, event?: Event, eventDetails?: RdxToggleGroupValueChangeEventDetails): void;
87
+ toggle(value: string, nextPressed: boolean, event?: Event, eventDetails?: RdxToggleGroupValueChangeEventDetails): void;
82
88
  /** @ignore */
83
89
  writeValue(value: string[] | string | null): void;
84
90
  /** @ignore */
@@ -114,7 +120,7 @@ declare class RdxToggleGroup extends RdxToggleGroupBase {
114
120
  private readonly activeIndex;
115
121
  constructor();
116
122
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxToggleGroup, never>;
117
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxToggleGroup, "[rdxToggleGroup]", ["rdxToggleGroup"], { "dirInput": { "alias": "dir"; "required": false; "isSignal": true; }; "loopFocus": { "alias": "loopFocus"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1.RdxCompositeRoot; inputs: {}; outputs: {}; }]>;
123
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxToggleGroup, "[rdxToggleGroup]", ["rdxToggleGroup"], { "dirInput": { "alias": "dir"; "required": false; "isSignal": true; }; "loopFocus": { "alias": "loopFocus"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1.RdxCompositeRoot; inputs: {}; outputs: {}; }, { directive: typeof _radix_ng_primitives_core.RdxFormUiStateHost; inputs: {}; outputs: {}; }]>;
118
124
  }
119
125
 
120
126
  /**
@@ -128,7 +134,7 @@ declare class RdxToggleGroupWithoutFocus extends RdxToggleGroupBase {
128
134
  private readonly toolbarGroupContext;
129
135
  protected isExternallyDisabled(): boolean;
130
136
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxToggleGroupWithoutFocus, never>;
131
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxToggleGroupWithoutFocus, "[rdxToggleGroupWithoutFocus]", ["rdxToggleGroupWithoutFocus"], {}, {}, never, never, true, never>;
137
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxToggleGroupWithoutFocus, "[rdxToggleGroupWithoutFocus]", ["rdxToggleGroupWithoutFocus"], {}, {}, never, never, true, [{ directive: typeof _radix_ng_primitives_core.RdxFormUiStateHost; inputs: {}; outputs: {}; }]>;
132
138
  }
133
139
 
134
140
  export { RdxToggleGroup, RdxToggleGroupBase, RdxToggleGroupWithoutFocus, injectToggleGroupContext, provideToggleGroupContext, toggleGroupContext };
@@ -1,7 +1,6 @@
1
1
  import * as _angular_core from '@angular/core';
2
2
  import { BooleanInput, RdxCancelableChangeEventDetails } from '@radix-ng/primitives/core';
3
3
  import * as i1 from '@radix-ng/primitives/composite';
4
- import * as i1$1 from '@radix-ng/primitives/visually-hidden';
5
4
 
6
5
  type RdxTogglePressedChangeReason = 'none';
7
6
  type RdxTogglePressedChangeEventDetails = RdxCancelableChangeEventDetails<RdxTogglePressedChangeReason>;
@@ -57,16 +56,17 @@ declare class RdxToggle {
57
56
  constructor();
58
57
  /** @ignore */
59
58
  protected onClick(event?: Event): void;
60
- /** @ignore */
59
+ /**
60
+ * @ignore
61
+ * Non-native hosts emulate a native `<button>` (Base UI `useButton`): Enter activates on keydown,
62
+ * Space is `preventDefault`-ed on keydown (to suppress page scroll) and activates on keyup.
63
+ */
61
64
  protected onKeyDown(event: KeyboardEvent): void;
65
+ /** @ignore Space activates on keyup for non-native hosts (native-button semantics). */
66
+ protected onKeyUp(event: KeyboardEvent): void;
62
67
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxToggle, never>;
63
68
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxToggle, "[rdxToggle]", ["rdxToggle"], { "value": { "alias": "value"; "required": false; "isSignal": true; }; "defaultPressed": { "alias": "defaultPressed"; "required": false; "isSignal": true; }; "pressed": { "alias": "pressed"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "nativeButton": { "alias": "nativeButton"; "required": false; "isSignal": true; }; }, { "pressed": "pressedChange"; "onPressedChange": "onPressedChange"; }, never, never, true, [{ directive: typeof i1.RdxCompositeItem; inputs: {}; outputs: {}; }]>;
64
69
  }
65
70
 
66
- declare class RdxToggleVisuallyHiddenInputDirective {
67
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxToggleVisuallyHiddenInputDirective, never>;
68
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxToggleVisuallyHiddenInputDirective, "input[rdxToggleVisuallyHiddenInput]", ["rdxToggleVisuallyHiddenInput"], {}, {}, never, never, true, [{ directive: typeof i1$1.RdxVisuallyHiddenInputBubbleDirective; inputs: { "name": "name"; "required": "required"; "value": "value"; "disabled": "disabled"; }; outputs: {}; }]>;
69
- }
70
-
71
- export { RdxToggle, RdxToggleVisuallyHiddenInputDirective };
71
+ export { RdxToggle };
72
72
  export type { RdxTogglePressedChangeEvent, RdxTogglePressedChangeEventDetails, RdxTogglePressedChangeReason };
@@ -94,6 +94,8 @@ declare class RdxToolbarInput {
94
94
  readonly isDisabled: _angular_core.Signal<boolean>;
95
95
  private appliedDefault;
96
96
  constructor();
97
+ /** @ignore Block pointer interaction while disabled (Base UI input `defaultProps`). */
98
+ protected onInteraction(event: Event): void;
97
99
  private handleCaretKeydown;
98
100
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxToolbarInput, never>;
99
101
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxToolbarInput, "input[rdxToolbarInput]", ["rdxToolbarInput"], { "defaultValue": { "alias": "defaultValue"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "focusableWhenDisabled": { "alias": "focusableWhenDisabled"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1.RdxCompositeItem; inputs: {}; outputs: {}; }]>;