@radix-ng/primitives 1.0.7 → 1.0.9

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 (54) hide show
  1. package/fesm2022/radix-ng-primitives-autocomplete.mjs +43 -9
  2. package/fesm2022/radix-ng-primitives-autocomplete.mjs.map +1 -1
  3. package/fesm2022/radix-ng-primitives-checkbox.mjs +89 -8
  4. package/fesm2022/radix-ng-primitives-checkbox.mjs.map +1 -1
  5. package/fesm2022/radix-ng-primitives-combobox.mjs +43 -9
  6. package/fesm2022/radix-ng-primitives-combobox.mjs.map +1 -1
  7. package/fesm2022/radix-ng-primitives-core.mjs +208 -2
  8. package/fesm2022/radix-ng-primitives-core.mjs.map +1 -1
  9. package/fesm2022/radix-ng-primitives-date-field.mjs +50 -9
  10. package/fesm2022/radix-ng-primitives-date-field.mjs.map +1 -1
  11. package/fesm2022/radix-ng-primitives-editable.mjs +31 -5
  12. package/fesm2022/radix-ng-primitives-editable.mjs.map +1 -1
  13. package/fesm2022/radix-ng-primitives-field.mjs +265 -46
  14. package/fesm2022/radix-ng-primitives-field.mjs.map +1 -1
  15. package/fesm2022/radix-ng-primitives-form.mjs +110 -26
  16. package/fesm2022/radix-ng-primitives-form.mjs.map +1 -1
  17. package/fesm2022/radix-ng-primitives-input.mjs +16 -6
  18. package/fesm2022/radix-ng-primitives-input.mjs.map +1 -1
  19. package/fesm2022/radix-ng-primitives-number-field.mjs +32 -7
  20. package/fesm2022/radix-ng-primitives-number-field.mjs.map +1 -1
  21. package/fesm2022/radix-ng-primitives-presence.mjs +4 -2
  22. package/fesm2022/radix-ng-primitives-presence.mjs.map +1 -1
  23. package/fesm2022/radix-ng-primitives-radio.mjs +18 -4
  24. package/fesm2022/radix-ng-primitives-radio.mjs.map +1 -1
  25. package/fesm2022/radix-ng-primitives-select.mjs +26 -8
  26. package/fesm2022/radix-ng-primitives-select.mjs.map +1 -1
  27. package/fesm2022/radix-ng-primitives-signal-forms.mjs +184 -0
  28. package/fesm2022/radix-ng-primitives-signal-forms.mjs.map +1 -0
  29. package/fesm2022/radix-ng-primitives-slider.mjs +24 -8
  30. package/fesm2022/radix-ng-primitives-slider.mjs.map +1 -1
  31. package/fesm2022/radix-ng-primitives-switch.mjs +29 -5
  32. package/fesm2022/radix-ng-primitives-switch.mjs.map +1 -1
  33. package/fesm2022/radix-ng-primitives-time-field.mjs +49 -9
  34. package/fesm2022/radix-ng-primitives-time-field.mjs.map +1 -1
  35. package/fesm2022/radix-ng-primitives-toggle-group.mjs +23 -12
  36. package/fesm2022/radix-ng-primitives-toggle-group.mjs.map +1 -1
  37. package/package.json +11 -1
  38. package/types/radix-ng-primitives-autocomplete.d.ts +21 -2
  39. package/types/radix-ng-primitives-checkbox.d.ts +53 -4
  40. package/types/radix-ng-primitives-combobox.d.ts +51 -2
  41. package/types/radix-ng-primitives-core.d.ts +206 -3
  42. package/types/radix-ng-primitives-date-field.d.ts +27 -2
  43. package/types/radix-ng-primitives-editable.d.ts +15 -2
  44. package/types/radix-ng-primitives-field.d.ts +136 -33
  45. package/types/radix-ng-primitives-form.d.ts +115 -21
  46. package/types/radix-ng-primitives-input.d.ts +8 -1
  47. package/types/radix-ng-primitives-number-field.d.ts +14 -3
  48. package/types/radix-ng-primitives-radio.d.ts +7 -2
  49. package/types/radix-ng-primitives-select.d.ts +11 -3
  50. package/types/radix-ng-primitives-signal-forms.d.ts +97 -0
  51. package/types/radix-ng-primitives-slider.d.ts +9 -7
  52. package/types/radix-ng-primitives-switch.d.ts +15 -2
  53. package/types/radix-ng-primitives-time-field.d.ts +26 -2
  54. package/types/radix-ng-primitives-toggle-group.d.ts +6 -4
@@ -2,7 +2,8 @@ import * as i0 from '@angular/core';
2
2
  import { model, input, booleanAttribute, output, computed, signal, effect, untracked, Directive, inject, ElementRef } from '@angular/core';
3
3
  import * as i1 from '@radix-ng/primitives/composite';
4
4
  import { RdxCompositeRoot } from '@radix-ng/primitives/composite';
5
- import { createCancelableChangeEventDetails, createContext, provideValueAccessor } from '@radix-ng/primitives/core';
5
+ import * as i2 from '@radix-ng/primitives/core';
6
+ import { RdxFormUiControlBase, createCancelableChangeEventDetails, createContext, provideValueAccessor, provideFormUiState, RdxFormUiStateHost } from '@radix-ng/primitives/core';
6
7
  import { injectDirection } from '@radix-ng/primitives/direction-provider';
7
8
  import { injectToolbarRootContext, injectToolbarGroupContext } from '@radix-ng/primitives/toolbar';
8
9
 
@@ -21,8 +22,9 @@ function toggleGroupContext(instance) {
21
22
  * ({@link RdxToggleGroup}) or omit it when an ancestor already owns focus, e.g. a toolbar
22
23
  * ({@link RdxToggleGroupWithoutFocus}).
23
24
  */
24
- class RdxToggleGroupBase {
25
+ class RdxToggleGroupBase extends RdxFormUiControlBase {
25
26
  constructor() {
27
+ super();
26
28
  /**
27
29
  * The pressed values. Always an array — a single value is `[value]`. Use with `(onValueChange)`
28
30
  * for controlled state.
@@ -71,6 +73,10 @@ class RdxToggleGroupBase {
71
73
  }
72
74
  });
73
75
  }
76
+ /** @ignore Bridge the CVA `onTouched` so `markAsTouched()` also notifies Reactive/template forms. */
77
+ formUiTouchTarget() {
78
+ return { markAsTouched: () => this.onTouched?.() };
79
+ }
74
80
  /** @ignore Extra disabled state inherited from composite parents such as Toolbar. */
75
81
  isExternallyDisabled() {
76
82
  return false;
@@ -101,6 +107,7 @@ class RdxToggleGroupBase {
101
107
  return;
102
108
  }
103
109
  this.value.set(next);
110
+ this.formUi.markDirty();
104
111
  this.onChange?.(next);
105
112
  }
106
113
  /** @ignore */
@@ -120,7 +127,7 @@ class RdxToggleGroupBase {
120
127
  this.accessorDisabled.set(isDisabled);
121
128
  }
122
129
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxToggleGroupBase, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
123
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: RdxToggleGroupBase, isStandalone: true, inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, defaultValue: { classPropertyName: "defaultValue", publicName: "defaultValue", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", onValueChange: "onValueChange" }, host: { attributes: { "role": "group" }, listeners: { "focusout": "onTouched?.()" }, properties: { "attr.data-orientation": "orientation()", "attr.data-disabled": "isDisabled() ? \"\" : undefined", "attr.data-multiple": "multiple() ? \"\" : undefined" } }, ngImport: i0 }); }
130
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: RdxToggleGroupBase, isStandalone: true, inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, defaultValue: { classPropertyName: "defaultValue", publicName: "defaultValue", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", onValueChange: "onValueChange" }, host: { attributes: { "role": "group" }, properties: { "attr.data-orientation": "orientation()", "attr.data-disabled": "isDisabled() ? \"\" : undefined", "attr.data-multiple": "multiple() ? \"\" : undefined" } }, usesInheritance: true, ngImport: i0 }); }
124
131
  }
125
132
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxToggleGroupBase, decorators: [{
126
133
  type: Directive,
@@ -129,8 +136,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImpor
129
136
  role: 'group',
130
137
  '[attr.data-orientation]': 'orientation()',
131
138
  '[attr.data-disabled]': 'isDisabled() ? "" : undefined',
132
- '[attr.data-multiple]': 'multiple() ? "" : undefined',
133
- '(focusout)': 'onTouched?.()'
139
+ '[attr.data-multiple]': 'multiple() ? "" : undefined'
134
140
  }
135
141
  }]
136
142
  }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], defaultValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValue", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], onValueChange: [{ type: i0.Output, args: ["onValueChange"] }] } });
@@ -195,18 +201,20 @@ class RdxToggleGroup extends RdxToggleGroupBase {
195
201
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxToggleGroup, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
196
202
  static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: RdxToggleGroup, isStandalone: true, selector: "[rdxToggleGroup]", inputs: { dirInput: { classPropertyName: "dirInput", publicName: "dir", isSignal: true, isRequired: false, transformFunction: null }, loopFocus: { classPropertyName: "loopFocus", publicName: "loopFocus", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
197
203
  provideToggleGroupContext(() => toggleGroupContext(inject(RdxToggleGroup))),
198
- provideValueAccessor(RdxToggleGroup)
199
- ], exportAs: ["rdxToggleGroup"], usesInheritance: true, hostDirectives: [{ directive: i1.RdxCompositeRoot }], ngImport: i0 }); }
204
+ provideValueAccessor(RdxToggleGroup),
205
+ provideFormUiState(() => inject(RdxToggleGroup).formUi)
206
+ ], exportAs: ["rdxToggleGroup"], usesInheritance: true, hostDirectives: [{ directive: i1.RdxCompositeRoot }, { directive: i2.RdxFormUiStateHost }], ngImport: i0 }); }
200
207
  }
201
208
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxToggleGroup, decorators: [{
202
209
  type: Directive,
203
210
  args: [{
204
211
  selector: '[rdxToggleGroup]',
205
212
  exportAs: 'rdxToggleGroup',
206
- hostDirectives: [RdxCompositeRoot],
213
+ hostDirectives: [RdxCompositeRoot, RdxFormUiStateHost],
207
214
  providers: [
208
215
  provideToggleGroupContext(() => toggleGroupContext(inject(RdxToggleGroup))),
209
- provideValueAccessor(RdxToggleGroup)
216
+ provideValueAccessor(RdxToggleGroup),
217
+ provideFormUiState(() => inject(RdxToggleGroup).formUi)
210
218
  ]
211
219
  }]
212
220
  }], ctorParameters: () => [], propDecorators: { dirInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "dir", required: false }] }], loopFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "loopFocus", required: false }] }] } });
@@ -232,17 +240,20 @@ class RdxToggleGroupWithoutFocus extends RdxToggleGroupBase {
232
240
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxToggleGroupWithoutFocus, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
233
241
  static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.2", type: RdxToggleGroupWithoutFocus, isStandalone: true, selector: "[rdxToggleGroupWithoutFocus]", providers: [
234
242
  provideToggleGroupContext(() => toggleGroupContext(inject(RdxToggleGroupWithoutFocus))),
235
- provideValueAccessor(RdxToggleGroupWithoutFocus)
236
- ], exportAs: ["rdxToggleGroupWithoutFocus"], usesInheritance: true, ngImport: i0 }); }
243
+ provideValueAccessor(RdxToggleGroupWithoutFocus),
244
+ provideFormUiState(() => inject(RdxToggleGroupWithoutFocus).formUi)
245
+ ], exportAs: ["rdxToggleGroupWithoutFocus"], usesInheritance: true, hostDirectives: [{ directive: i2.RdxFormUiStateHost }], ngImport: i0 }); }
237
246
  }
238
247
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxToggleGroupWithoutFocus, decorators: [{
239
248
  type: Directive,
240
249
  args: [{
241
250
  selector: '[rdxToggleGroupWithoutFocus]',
242
251
  exportAs: 'rdxToggleGroupWithoutFocus',
252
+ hostDirectives: [RdxFormUiStateHost],
243
253
  providers: [
244
254
  provideToggleGroupContext(() => toggleGroupContext(inject(RdxToggleGroupWithoutFocus))),
245
- provideValueAccessor(RdxToggleGroupWithoutFocus)
255
+ provideValueAccessor(RdxToggleGroupWithoutFocus),
256
+ provideFormUiState(() => inject(RdxToggleGroupWithoutFocus).formUi)
246
257
  ]
247
258
  }]
248
259
  }] });
@@ -1 +1 @@
1
- {"version":3,"file":"radix-ng-primitives-toggle-group.mjs","sources":["../../../packages/primitives/toggle-group/src/toggle-group-base.ts","../../../packages/primitives/toggle-group/src/toggle-group-context.ts","../../../packages/primitives/toggle-group/src/toggle-group.ts","../../../packages/primitives/toggle-group/src/toggle-group-without-focus.ts","../../../packages/primitives/toggle-group/radix-ng-primitives-toggle-group.ts"],"sourcesContent":["import { booleanAttribute, computed, Directive, effect, input, model, output, signal, untracked } from '@angular/core';\nimport { ControlValueAccessor } from '@angular/forms';\nimport {\n BooleanInput,\n createCancelableChangeEventDetails,\n DataOrientation,\n RdxCancelableChangeEventDetails\n} from '@radix-ng/primitives/core';\nimport { RdxToggleGroupContext } from './toggle-group-context';\n\nexport type RdxToggleGroupValueChangeReason = 'none';\nexport type RdxToggleGroupValueChangeEventDetails = RdxCancelableChangeEventDetails<RdxToggleGroupValueChangeReason>;\n\nexport interface RdxToggleGroupValueChangeEvent {\n value: string[];\n eventDetails: RdxToggleGroupValueChangeEventDetails;\n}\n\n/** Builds the shared context a {@link RdxToggle} reads when it belongs to this group. */\nexport function toggleGroupContext(instance: RdxToggleGroupBase): RdxToggleGroupContext {\n return {\n value: instance.pressedValues,\n disabled: instance.isDisabled,\n orientation: instance.orientation,\n isValueInitialized: instance.isValueInitialized,\n toggle: (value, nextPressed, event, eventDetails) => instance.toggle(value, nextPressed, event, eventDetails)\n };\n}\n\n/**\n * Shared state and behavior for the toggle group. Concrete directives add the composite root\n * ({@link RdxToggleGroup}) or omit it when an ancestor already owns focus, e.g. a toolbar\n * ({@link RdxToggleGroupWithoutFocus}).\n */\n@Directive({\n host: {\n role: 'group',\n '[attr.data-orientation]': 'orientation()',\n '[attr.data-disabled]': 'isDisabled() ? \"\" : undefined',\n '[attr.data-multiple]': 'multiple() ? \"\" : undefined',\n '(focusout)': 'onTouched?.()'\n }\n})\nexport abstract class RdxToggleGroupBase implements ControlValueAccessor {\n /**\n * The pressed values. Always an array — a single value is `[value]`. Use with `(onValueChange)`\n * for controlled state.\n */\n readonly value = model<string[]>();\n\n /** The values pressed when the group is initially rendered (uncontrolled). */\n readonly defaultValue = input<string[]>();\n\n /**\n * Whether multiple items can be pressed at the same time.\n *\n * @default false\n */\n readonly multiple = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /**\n * Whether the whole group is disabled.\n *\n * @default false\n */\n readonly disabled = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /**\n * The orientation of the group, controlling arrow-key navigation.\n *\n * @default 'horizontal'\n */\n readonly orientation = input<DataOrientation>('horizontal');\n\n /** Event emitted when the pressed values change. */\n readonly onValueChange = output<RdxToggleGroupValueChangeEvent>();\n\n /** @ignore */\n readonly pressedValues = computed(() => this.value() ?? []);\n /** @ignore */\n readonly isValueInitialized = computed(() => this.value() !== undefined || this.defaultValue() !== undefined);\n\n protected readonly accessorDisabled = signal(false);\n /** @ignore */\n readonly isDisabled = computed(() => this.disabled() || this.accessorDisabled() || this.isExternallyDisabled());\n\n private onChange?: (value: string[]) => void;\n protected onTouched?: () => void;\n\n constructor() {\n effect(() => {\n const initial = this.defaultValue();\n if (initial !== undefined && untracked(this.value) === undefined) {\n this.value.set(initial);\n }\n });\n }\n\n /** @ignore Extra disabled state inherited from composite parents such as Toolbar. */\n protected isExternallyDisabled(): boolean {\n return false;\n }\n\n /** @ignore */\n toggle(\n value: string,\n nextPressed: boolean,\n event?: Event,\n eventDetails?: RdxToggleGroupValueChangeEventDetails\n ): void {\n if (this.isDisabled()) {\n return;\n }\n\n const current = this.pressedValues();\n let next: string[];\n\n // The item supplies the next pressed boolean (source of truth); the group only maps it onto its\n // value set — add `value` when pressed, remove it when not.\n if (this.multiple()) {\n next = nextPressed\n ? current.includes(value)\n ? current\n : [...current, value]\n : current.filter((item) => item !== value);\n } else {\n next = nextPressed ? [value] : [];\n }\n\n const resolvedEventDetails =\n eventDetails ??\n createCancelableChangeEventDetails(\n 'none',\n event ?? new Event('toggle-group.value-change'),\n event?.currentTarget instanceof HTMLElement ? event.currentTarget : undefined\n ).eventDetails;\n\n this.onValueChange.emit({ value: next, eventDetails: resolvedEventDetails });\n if (resolvedEventDetails.isCanceled()) {\n return;\n }\n\n this.value.set(next);\n this.onChange?.(next);\n }\n\n /** @ignore */\n writeValue(value: string[] | string | null): void {\n this.value.set(value == null ? [] : Array.isArray(value) ? value : [value]);\n }\n\n /** @ignore */\n registerOnChange(fn: (value: string[]) => void): void {\n this.onChange = fn;\n }\n\n /** @ignore */\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n /** @ignore */\n setDisabledState(isDisabled: boolean): void {\n this.accessorDisabled.set(isDisabled);\n }\n}\n","import { Signal } from '@angular/core';\nimport { createContext, DataOrientation, RdxCancelableChangeEventDetails } from '@radix-ng/primitives/core';\n\ntype RdxToggleGroupContextChangeReason = 'none';\n\n/**\n * Shared state a {@link RdxToggle} reads when it participates in a toggle group.\n */\nexport interface RdxToggleGroupContext {\n /** The currently pressed values. */\n readonly value: Signal<string[]>;\n\n /** Whether the whole group is disabled. */\n readonly disabled: Signal<boolean>;\n\n /** The orientation of the group. */\n readonly orientation: Signal<DataOrientation>;\n\n /** Whether the group value was initialized by `value` or `defaultValue`. */\n readonly isValueInitialized: Signal<boolean>;\n\n /**\n * Set the pressed state of `value` within the group. The item computes the next pressed boolean\n * (Base UI parity — the item is the source of truth), so the group applies it rather than\n * re-deriving the toggle from its current value set.\n */\n toggle(\n value: string,\n nextPressed: boolean,\n event?: Event,\n eventDetails?: RdxCancelableChangeEventDetails<RdxToggleGroupContextChangeReason>\n ): void;\n}\n\nexport const [injectToggleGroupContext, provideToggleGroupContext] = createContext<RdxToggleGroupContext>(\n 'RdxToggleGroupContext',\n 'components/toggle-group'\n);\n","import { booleanAttribute, computed, Directive, effect, ElementRef, inject, input } from '@angular/core';\nimport { RdxCompositeMetadata, RdxCompositeRoot } from '@radix-ng/primitives/composite';\nimport { BooleanInput, Direction, provideValueAccessor } from '@radix-ng/primitives/core';\nimport { injectDirection } from '@radix-ng/primitives/direction-provider';\nimport { RdxToggleGroupBase, toggleGroupContext } from './toggle-group-base';\nimport { provideToggleGroupContext } from './toggle-group-context';\n\n/**\n * A set of two-state buttons that can be toggled on or off. Owns composite keyboard focus over its\n * `[rdxToggle]` children.\n *\n * @see https://base-ui.com/react/components/toggle-group\n */\n@Directive({\n selector: '[rdxToggleGroup]',\n exportAs: 'rdxToggleGroup',\n hostDirectives: [RdxCompositeRoot],\n providers: [\n provideToggleGroupContext(() => toggleGroupContext(inject(RdxToggleGroup))),\n provideValueAccessor(RdxToggleGroup)\n ]\n})\nexport class RdxToggleGroup extends RdxToggleGroupBase {\n private readonly elementRef = inject<ElementRef<HTMLElement>>(ElementRef);\n\n /** Text direction for arrow-key navigation. */\n readonly dirInput = input<Direction | undefined>(undefined, { alias: 'dir' });\n readonly dir = injectDirection(this.dirInput);\n\n /**\n * Whether keyboard navigation should loop from the last item back to the first.\n *\n * @default true\n */\n readonly loopFocus = input<boolean, BooleanInput>(true, { transform: booleanAttribute });\n\n private readonly compositeRoot = inject(RdxCompositeRoot, { self: true });\n private readonly itemMetadata = computed(() =>\n Array.from(this.compositeRoot.itemMap().values()).filter(isToggleItemMetadata)\n );\n private readonly disabledIndices = computed(() =>\n this.itemMetadata()\n .filter((metadata) => metadata.disabled)\n .map((metadata) => metadata.index)\n );\n private readonly activeIndex = computed(() => {\n const pressedValues = this.pressedValues();\n if (pressedValues.length === 0) {\n return -1;\n }\n\n return this.itemMetadata().find((metadata) => pressedValues.includes(metadata.value))?.index ?? -1;\n });\n\n constructor() {\n super();\n\n effect(() => {\n this.compositeRoot.setOrientation(this.orientation());\n this.compositeRoot.setDir(this.dir());\n this.compositeRoot.setLoopFocus(this.loopFocus());\n this.compositeRoot.setEnableHomeAndEndKeys(true);\n });\n\n effect(() => {\n this.compositeRoot.setDisabledIndices(this.disabledIndices());\n });\n\n effect(() => {\n const activeIndex = this.activeIndex();\n\n if (activeIndex === -1 || this.disabledIndices().includes(activeIndex)) {\n return;\n }\n\n const activeElement = this.elementRef.nativeElement.ownerDocument.activeElement;\n if (activeElement && this.elementRef.nativeElement.contains(activeElement)) {\n return;\n }\n\n this.compositeRoot.setHighlightedIndex(activeIndex);\n });\n }\n}\n\ninterface RdxToggleItemMetadata {\n [key: string]: unknown;\n disabled: boolean;\n value: string;\n}\n\nfunction isToggleItemMetadata(metadata: RdxCompositeMetadata): metadata is RdxCompositeMetadata<RdxToggleItemMetadata> {\n return typeof metadata['disabled'] === 'boolean' && typeof metadata['value'] === 'string';\n}\n","import { Directive, inject } from '@angular/core';\nimport { provideValueAccessor } from '@radix-ng/primitives/core';\nimport { injectToolbarGroupContext, injectToolbarRootContext } from '@radix-ng/primitives/toolbar';\nimport { RdxToggleGroupBase, toggleGroupContext } from './toggle-group-base';\nimport { provideToggleGroupContext } from './toggle-group-context';\n\n/**\n * A toggle group that does NOT create its own composite root, for use inside a container that\n * already owns keyboard focus (e.g. a toolbar). The `[rdxToggle]` children register with the nearest\n * ancestor composite root instead. Mirrors Base UI's behavior of skipping its composite root\n * when nested in a toolbar.\n */\n@Directive({\n selector: '[rdxToggleGroupWithoutFocus]',\n exportAs: 'rdxToggleGroupWithoutFocus',\n providers: [\n provideToggleGroupContext(() => toggleGroupContext(inject(RdxToggleGroupWithoutFocus))),\n provideValueAccessor(RdxToggleGroupWithoutFocus)\n ]\n})\nexport class RdxToggleGroupWithoutFocus extends RdxToggleGroupBase {\n private readonly toolbarRootContext = injectToolbarRootContext(true);\n private readonly toolbarGroupContext = injectToolbarGroupContext(true);\n\n protected override isExternallyDisabled(): boolean {\n return (this.toolbarRootContext?.disabled() ?? false) || (this.toolbarGroupContext?.disabled() ?? false);\n }\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-toggle-group.mjs","sources":["../../../packages/primitives/toggle-group/src/toggle-group-base.ts","../../../packages/primitives/toggle-group/src/toggle-group-context.ts","../../../packages/primitives/toggle-group/src/toggle-group.ts","../../../packages/primitives/toggle-group/src/toggle-group-without-focus.ts","../../../packages/primitives/toggle-group/radix-ng-primitives-toggle-group.ts"],"sourcesContent":["import { booleanAttribute, computed, Directive, effect, input, model, output, signal, untracked } from '@angular/core';\nimport { ControlValueAccessor } from '@angular/forms';\nimport {\n BooleanInput,\n createCancelableChangeEventDetails,\n DataOrientation,\n RdxCancelableChangeEventDetails,\n RdxFormUiControlBase,\n RdxFormUiTouchTarget,\n RdxFormValueControl\n} from '@radix-ng/primitives/core';\nimport { RdxToggleGroupContext } from './toggle-group-context';\n\nexport type RdxToggleGroupValueChangeReason = 'none';\nexport type RdxToggleGroupValueChangeEventDetails = RdxCancelableChangeEventDetails<RdxToggleGroupValueChangeReason>;\n\nexport interface RdxToggleGroupValueChangeEvent {\n value: string[];\n eventDetails: RdxToggleGroupValueChangeEventDetails;\n}\n\n/** Builds the shared context a {@link RdxToggle} reads when it belongs to this group. */\nexport function toggleGroupContext(instance: RdxToggleGroupBase): RdxToggleGroupContext {\n return {\n value: instance.pressedValues,\n disabled: instance.isDisabled,\n orientation: instance.orientation,\n isValueInitialized: instance.isValueInitialized,\n toggle: (value, nextPressed, event, eventDetails) => instance.toggle(value, nextPressed, event, eventDetails)\n };\n}\n\n/**\n * Shared state and behavior for the toggle group. Concrete directives add the composite root\n * ({@link RdxToggleGroup}) or omit it when an ancestor already owns focus, e.g. a toolbar\n * ({@link RdxToggleGroupWithoutFocus}).\n */\n@Directive({\n host: {\n role: 'group',\n '[attr.data-orientation]': 'orientation()',\n '[attr.data-disabled]': 'isDisabled() ? \"\" : undefined',\n '[attr.data-multiple]': 'multiple() ? \"\" : undefined'\n }\n})\nexport abstract class RdxToggleGroupBase\n extends RdxFormUiControlBase\n implements ControlValueAccessor, RdxFormValueControl<string[] | undefined>\n{\n /**\n * The pressed values. Always an array — a single value is `[value]`. Use with `(onValueChange)`\n * for controlled state.\n */\n readonly value = model<string[]>();\n\n /** The values pressed when the group is initially rendered (uncontrolled). */\n readonly defaultValue = input<string[]>();\n\n /**\n * Whether multiple items can be pressed at the same time.\n *\n * @default false\n */\n readonly multiple = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /**\n * Whether the whole group is disabled.\n *\n * @default false\n */\n readonly disabled = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /**\n * The orientation of the group, controlling arrow-key navigation.\n *\n * @default 'horizontal'\n */\n readonly orientation = input<DataOrientation>('horizontal');\n\n /** Event emitted when the pressed values change. */\n readonly onValueChange = output<RdxToggleGroupValueChangeEvent>();\n\n /** @ignore */\n readonly pressedValues = computed(() => this.value() ?? []);\n /** @ignore */\n readonly isValueInitialized = computed(() => this.value() !== undefined || this.defaultValue() !== undefined);\n\n protected readonly accessorDisabled = signal(false);\n /** @ignore */\n readonly isDisabled = computed(() => this.disabled() || this.accessorDisabled() || this.isExternallyDisabled());\n\n private onChange?: (value: string[]) => void;\n protected onTouched?: () => void;\n\n constructor() {\n super();\n\n effect(() => {\n const initial = this.defaultValue();\n if (initial !== undefined && untracked(this.value) === undefined) {\n this.value.set(initial);\n }\n });\n }\n\n /** @ignore Bridge the CVA `onTouched` so `markAsTouched()` also notifies Reactive/template forms. */\n protected override formUiTouchTarget(): RdxFormUiTouchTarget {\n return { markAsTouched: () => this.onTouched?.() };\n }\n\n /** @ignore Extra disabled state inherited from composite parents such as Toolbar. */\n protected isExternallyDisabled(): boolean {\n return false;\n }\n\n /** @ignore */\n toggle(\n value: string,\n nextPressed: boolean,\n event?: Event,\n eventDetails?: RdxToggleGroupValueChangeEventDetails\n ): void {\n if (this.isDisabled()) {\n return;\n }\n\n const current = this.pressedValues();\n let next: string[];\n\n // The item supplies the next pressed boolean (source of truth); the group only maps it onto its\n // value set — add `value` when pressed, remove it when not.\n if (this.multiple()) {\n next = nextPressed\n ? current.includes(value)\n ? current\n : [...current, value]\n : current.filter((item) => item !== value);\n } else {\n next = nextPressed ? [value] : [];\n }\n\n const resolvedEventDetails =\n eventDetails ??\n createCancelableChangeEventDetails(\n 'none',\n event ?? new Event('toggle-group.value-change'),\n event?.currentTarget instanceof HTMLElement ? event.currentTarget : undefined\n ).eventDetails;\n\n this.onValueChange.emit({ value: next, eventDetails: resolvedEventDetails });\n if (resolvedEventDetails.isCanceled()) {\n return;\n }\n\n this.value.set(next);\n this.formUi.markDirty();\n this.onChange?.(next);\n }\n\n /** @ignore */\n writeValue(value: string[] | string | null): void {\n this.value.set(value == null ? [] : Array.isArray(value) ? value : [value]);\n }\n\n /** @ignore */\n registerOnChange(fn: (value: string[]) => void): void {\n this.onChange = fn;\n }\n\n /** @ignore */\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n /** @ignore */\n setDisabledState(isDisabled: boolean): void {\n this.accessorDisabled.set(isDisabled);\n }\n}\n","import { Signal } from '@angular/core';\nimport { createContext, DataOrientation, RdxCancelableChangeEventDetails } from '@radix-ng/primitives/core';\n\ntype RdxToggleGroupContextChangeReason = 'none';\n\n/**\n * Shared state a {@link RdxToggle} reads when it participates in a toggle group.\n */\nexport interface RdxToggleGroupContext {\n /** The currently pressed values. */\n readonly value: Signal<string[]>;\n\n /** Whether the whole group is disabled. */\n readonly disabled: Signal<boolean>;\n\n /** The orientation of the group. */\n readonly orientation: Signal<DataOrientation>;\n\n /** Whether the group value was initialized by `value` or `defaultValue`. */\n readonly isValueInitialized: Signal<boolean>;\n\n /**\n * Set the pressed state of `value` within the group. The item computes the next pressed boolean\n * (Base UI parity — the item is the source of truth), so the group applies it rather than\n * re-deriving the toggle from its current value set.\n */\n toggle(\n value: string,\n nextPressed: boolean,\n event?: Event,\n eventDetails?: RdxCancelableChangeEventDetails<RdxToggleGroupContextChangeReason>\n ): void;\n}\n\nexport const [injectToggleGroupContext, provideToggleGroupContext] = createContext<RdxToggleGroupContext>(\n 'RdxToggleGroupContext',\n 'components/toggle-group'\n);\n","import { booleanAttribute, computed, Directive, effect, ElementRef, inject, input } from '@angular/core';\nimport { RdxCompositeMetadata, RdxCompositeRoot } from '@radix-ng/primitives/composite';\nimport {\n BooleanInput,\n Direction,\n provideFormUiState,\n provideValueAccessor,\n RdxFormUiStateHost\n} from '@radix-ng/primitives/core';\nimport { injectDirection } from '@radix-ng/primitives/direction-provider';\nimport { RdxToggleGroupBase, toggleGroupContext } from './toggle-group-base';\nimport { provideToggleGroupContext } from './toggle-group-context';\n\n/**\n * A set of two-state buttons that can be toggled on or off. Owns composite keyboard focus over its\n * `[rdxToggle]` children.\n *\n * @see https://base-ui.com/react/components/toggle-group\n */\n@Directive({\n selector: '[rdxToggleGroup]',\n exportAs: 'rdxToggleGroup',\n hostDirectives: [RdxCompositeRoot, RdxFormUiStateHost],\n providers: [\n provideToggleGroupContext(() => toggleGroupContext(inject(RdxToggleGroup))),\n provideValueAccessor(RdxToggleGroup),\n provideFormUiState(() => inject(RdxToggleGroup).formUi)\n ]\n})\nexport class RdxToggleGroup extends RdxToggleGroupBase {\n private readonly elementRef = inject<ElementRef<HTMLElement>>(ElementRef);\n\n /** Text direction for arrow-key navigation. */\n readonly dirInput = input<Direction | undefined>(undefined, { alias: 'dir' });\n readonly dir = injectDirection(this.dirInput);\n\n /**\n * Whether keyboard navigation should loop from the last item back to the first.\n *\n * @default true\n */\n readonly loopFocus = input<boolean, BooleanInput>(true, { transform: booleanAttribute });\n\n private readonly compositeRoot = inject(RdxCompositeRoot, { self: true });\n private readonly itemMetadata = computed(() =>\n Array.from(this.compositeRoot.itemMap().values()).filter(isToggleItemMetadata)\n );\n private readonly disabledIndices = computed(() =>\n this.itemMetadata()\n .filter((metadata) => metadata.disabled)\n .map((metadata) => metadata.index)\n );\n private readonly activeIndex = computed(() => {\n const pressedValues = this.pressedValues();\n if (pressedValues.length === 0) {\n return -1;\n }\n\n return this.itemMetadata().find((metadata) => pressedValues.includes(metadata.value))?.index ?? -1;\n });\n\n constructor() {\n super();\n\n effect(() => {\n this.compositeRoot.setOrientation(this.orientation());\n this.compositeRoot.setDir(this.dir());\n this.compositeRoot.setLoopFocus(this.loopFocus());\n this.compositeRoot.setEnableHomeAndEndKeys(true);\n });\n\n effect(() => {\n this.compositeRoot.setDisabledIndices(this.disabledIndices());\n });\n\n effect(() => {\n const activeIndex = this.activeIndex();\n\n if (activeIndex === -1 || this.disabledIndices().includes(activeIndex)) {\n return;\n }\n\n const activeElement = this.elementRef.nativeElement.ownerDocument.activeElement;\n if (activeElement && this.elementRef.nativeElement.contains(activeElement)) {\n return;\n }\n\n this.compositeRoot.setHighlightedIndex(activeIndex);\n });\n }\n}\n\ninterface RdxToggleItemMetadata {\n [key: string]: unknown;\n disabled: boolean;\n value: string;\n}\n\nfunction isToggleItemMetadata(metadata: RdxCompositeMetadata): metadata is RdxCompositeMetadata<RdxToggleItemMetadata> {\n return typeof metadata['disabled'] === 'boolean' && typeof metadata['value'] === 'string';\n}\n","import { Directive, inject } from '@angular/core';\nimport { provideFormUiState, provideValueAccessor, RdxFormUiStateHost } from '@radix-ng/primitives/core';\nimport { injectToolbarGroupContext, injectToolbarRootContext } from '@radix-ng/primitives/toolbar';\nimport { RdxToggleGroupBase, toggleGroupContext } from './toggle-group-base';\nimport { provideToggleGroupContext } from './toggle-group-context';\n\n/**\n * A toggle group that does NOT create its own composite root, for use inside a container that\n * already owns keyboard focus (e.g. a toolbar). The `[rdxToggle]` children register with the nearest\n * ancestor composite root instead. Mirrors Base UI's behavior of skipping its composite root\n * when nested in a toolbar.\n */\n@Directive({\n selector: '[rdxToggleGroupWithoutFocus]',\n exportAs: 'rdxToggleGroupWithoutFocus',\n hostDirectives: [RdxFormUiStateHost],\n providers: [\n provideToggleGroupContext(() => toggleGroupContext(inject(RdxToggleGroupWithoutFocus))),\n provideValueAccessor(RdxToggleGroupWithoutFocus),\n provideFormUiState(() => inject(RdxToggleGroupWithoutFocus).formUi)\n ]\n})\nexport class RdxToggleGroupWithoutFocus extends RdxToggleGroupBase {\n private readonly toolbarRootContext = injectToolbarRootContext(true);\n private readonly toolbarGroupContext = injectToolbarGroupContext(true);\n\n protected override isExternallyDisabled(): boolean {\n return (this.toolbarRootContext?.disabled() ?? false) || (this.toolbarGroupContext?.disabled() ?? false);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@radix-ng/primitives",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "description": "Headless, signals-first UI primitives for Angular.",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -20,10 +20,16 @@
20
20
  ],
21
21
  "peerDependencies": {
22
22
  "@angular/core": "^21.0.0 || ^22.0.0",
23
+ "@angular/forms": "^21.0.0 || ^22.0.0",
23
24
  "@floating-ui/dom": "^1.7.6",
24
25
  "@internationalized/date": "^3.12.2",
25
26
  "@internationalized/number": "^3.6.7"
26
27
  },
28
+ "peerDependenciesMeta": {
29
+ "@angular/forms": {
30
+ "optional": true
31
+ }
32
+ },
27
33
  "schematics": "./schematics/collection.json",
28
34
  "sideEffects": false,
29
35
  "ng-add": {
@@ -223,6 +229,10 @@
223
229
  "types": "./types/radix-ng-primitives-separator.d.ts",
224
230
  "default": "./fesm2022/radix-ng-primitives-separator.mjs"
225
231
  },
232
+ "./signal-forms": {
233
+ "types": "./types/radix-ng-primitives-signal-forms.d.ts",
234
+ "default": "./fesm2022/radix-ng-primitives-signal-forms.mjs"
235
+ },
226
236
  "./slider": {
227
237
  "types": "./types/radix-ng-primitives-slider.d.ts",
228
238
  "default": "./fesm2022/radix-ng-primitives-slider.mjs"
@@ -3,7 +3,7 @@ import * as _radix_ng_primitives_combobox from '@radix-ng/primitives/combobox';
3
3
  import { RdxComboboxOpenChange, ComboboxItemHighlightedDetails, ComboboxInputLayout, ComboboxItemRef, RdxComboboxOpenChangeReason, ComboboxHighlightReason } from '@radix-ng/primitives/combobox';
4
4
  export { ComboboxHighlightReason as AutocompleteHighlightReason, ComboboxItemHighlightedDetails as AutocompleteItemHighlightedDetails } from '@radix-ng/primitives/combobox';
5
5
  import * as _radix_ng_primitives_core from '@radix-ng/primitives/core';
6
- import { AcceptableValue, RdxCancelableChangeEventDetails, RdxFloatingRootContext, Direction, BooleanInput, ItemValueComparator } from '@radix-ng/primitives/core';
6
+ import { AcceptableValue, RdxCancelableChangeEventDetails, RdxFormUiControlBase, RdxFormValueControl, RdxFloatingRootContext, Direction, BooleanInput, ItemValueComparator, RdxFormUiTouchTarget } from '@radix-ng/primitives/core';
7
7
  import { ControlValueAccessor } from '@angular/forms';
8
8
  import * as i1 from '@radix-ng/primitives/popper';
9
9
  import { RdxPopperContentWrapper } from '@radix-ng/primitives/popper';
@@ -57,7 +57,7 @@ interface AutocompleteValueChangeDetails {
57
57
  *
58
58
  * @group Components
59
59
  */
60
- declare class RdxAutocompleteRoot implements ControlValueAccessor {
60
+ declare class RdxAutocompleteRoot extends RdxFormUiControlBase implements ControlValueAccessor, RdxFormValueControl<string> {
61
61
  private readonly injector;
62
62
  /** Per-popup floating root context (ADR 0015) — `open` / `triggers` / reference for the dismissal engine. */
63
63
  readonly floatingContext: RdxFloatingRootContext;
@@ -133,6 +133,12 @@ declare class RdxAutocompleteRoot implements ControlValueAccessor {
133
133
  private readonly cvaDisabled;
134
134
  readonly disabledState: _angular_core.Signal<boolean>;
135
135
  readonly requiredState: _angular_core.Signal<boolean>;
136
+ /** @ignore */
137
+ readonly invalidState: _angular_core.Signal<boolean>;
138
+ /** @ignore */
139
+ readonly touchedState: _angular_core.Signal<boolean>;
140
+ /** @ignore */
141
+ readonly dirtyState: _angular_core.Signal<boolean>;
136
142
  private readonly preventUnmountOnClose;
137
143
  readonly present: _angular_core.Signal<boolean>;
138
144
  /** Whether built-in filtering applies in the current mode (`list` / `both`). */
@@ -210,6 +216,8 @@ declare class RdxAutocompleteRoot implements ControlValueAccessor {
210
216
  setKeyboardActive(value: boolean): void;
211
217
  clearValue(): void;
212
218
  focusInput(): void;
219
+ /** @ignore Bridge the CVA `onTouched` so `markAsTouched()` also notifies Reactive/template forms. */
220
+ protected formUiTouchTarget(): RdxFormUiTouchTarget;
213
221
  markAsTouched(): void;
214
222
  private commitValue;
215
223
  private createOpenChangeEvent;
@@ -263,8 +271,16 @@ declare class RdxAutocompleteInput {
263
271
  readonly invalid: _angular_core.InputSignalWithTransform<boolean, BooleanInput>;
264
272
  protected readonly ariaAutocomplete: _angular_core.Signal<_radix_ng_primitives_autocomplete.AutocompleteMode>;
265
273
  protected readonly invalidState: _angular_core.Signal<boolean>;
274
+ /**
275
+ * Tri-state *displayed* validity: the enclosing Field's gated `validState` when inside a `rdxFieldRoot`
276
+ * (so a field whose `validationMode` defers display (e.g. `onBlur`) keeps the input neutral until revealed), else the input's
277
+ * own binary invalidity.
278
+ */
279
+ protected readonly displayValid: _angular_core.Signal<boolean | null>;
266
280
  protected readonly disabledState: _angular_core.Signal<boolean>;
267
281
  protected readonly requiredState: _angular_core.Signal<boolean>;
282
+ protected readonly touchedState: _angular_core.Signal<boolean>;
283
+ protected readonly dirtyState: _angular_core.Signal<boolean>;
268
284
  protected readonly filledState: _angular_core.Signal<boolean>;
269
285
  protected readonly focusedState: _angular_core.Signal<boolean>;
270
286
  protected readonly describedBy: _angular_core.Signal<string | undefined>;
@@ -578,6 +594,9 @@ declare class RdxAutocompleteEmpty {
578
594
  disabledState: _angular_core.Signal<boolean>;
579
595
  readonly: _angular_core.InputSignalWithTransform<boolean, unknown>;
580
596
  requiredState: _angular_core.Signal<boolean>;
597
+ invalidState: _angular_core.Signal<boolean>;
598
+ touchedState: _angular_core.Signal<boolean>;
599
+ dirtyState: _angular_core.Signal<boolean>;
581
600
  openOnInputClick: _angular_core.InputSignalWithTransform<boolean, unknown>;
582
601
  modal: _angular_core.InputSignalWithTransform<boolean, unknown>;
583
602
  virtualized: _angular_core.InputSignalWithTransform<boolean, unknown>;
@@ -2,7 +2,7 @@ import * as _angular_core from '@angular/core';
2
2
  import { Signal } from '@angular/core';
3
3
  import * as _radix_ng_primitives_checkbox from '@radix-ng/primitives/checkbox';
4
4
  import * as _radix_ng_primitives_core from '@radix-ng/primitives/core';
5
- import { RdxCancelableChangeEventDetails, RdxFormCheckboxControl, BooleanInput } from '@radix-ng/primitives/core';
5
+ import { RdxCancelableChangeEventDetails, RdxFormCheckboxControl, BooleanInput, RdxValidationError, RdxFormUiControlBase, RdxFormValueControl, RdxFormUiTouchTarget } from '@radix-ng/primitives/core';
6
6
  import { ControlValueAccessor } from '@angular/forms';
7
7
 
8
8
  /**
@@ -49,6 +49,11 @@ interface CheckboxRootContext {
49
49
  form: Signal<string | undefined>;
50
50
  readonly: Signal<boolean>;
51
51
  state: Signal<'indeterminate' | 'checked' | 'unchecked'>;
52
+ invalidState: Signal<boolean>;
53
+ /** Tri-state displayed validity (`true`/`false`/`null`) — the field's gated state when standalone in a Field. */
54
+ displayValid: Signal<boolean | null>;
55
+ touchedState: Signal<boolean>;
56
+ dirtyState: Signal<boolean>;
52
57
  uncheckedValue: Signal<string | undefined>;
53
58
  toggle: (event?: Event) => void;
54
59
  }
@@ -121,6 +126,27 @@ declare class RdxCheckboxRootDirective implements RdxFormCheckboxControl {
121
126
  * @group Props
122
127
  */
123
128
  readonly required: _angular_core.InputSignalWithTransform<boolean, BooleanInput>;
129
+ /**
130
+ * Whether the checkbox is invalid. A non-empty {@link errors} list also marks it invalid.
131
+ * @group Props
132
+ */
133
+ readonly invalid: _angular_core.InputSignalWithTransform<boolean, BooleanInput>;
134
+ /**
135
+ * Whether the checkbox has been touched. A `model()` so Signal Forms can write it; the checkbox
136
+ * also sets it on toggle (and emits {@link touch}).
137
+ * @group Props
138
+ */
139
+ readonly touched: _angular_core.ModelSignal<boolean>;
140
+ /**
141
+ * Whether the checked state changed from its initial value. Merged with internal tracking.
142
+ * @group Props
143
+ */
144
+ readonly dirty: _angular_core.InputSignalWithTransform<boolean, BooleanInput>;
145
+ /**
146
+ * Validation errors for the checkbox. A non-empty list marks it invalid.
147
+ * @group Props
148
+ */
149
+ readonly errors: _angular_core.InputSignal<readonly RdxValidationError[]>;
124
150
  /**
125
151
  * Name of the form control. Submitted with the form as part of a name/value pair. Inside a
126
152
  * `rdxCheckboxGroup` this also identifies the checkbox in the group's value array.
@@ -143,6 +169,11 @@ declare class RdxCheckboxRootDirective implements RdxFormCheckboxControl {
143
169
  * @group Emits
144
170
  */
145
171
  readonly onCheckedChange: _angular_core.OutputEmitterRef<RdxCheckboxCheckedChangeEvent>;
172
+ /**
173
+ * Emits on interaction, notifying Signal Forms the checkbox was touched.
174
+ * @group Emits
175
+ */
176
+ readonly touch: _angular_core.OutputEmitterRef<void>;
146
177
  /**
147
178
  * @ignore
148
179
  * The effective checked state as a `boolean`. Inside a `rdxCheckboxGroup` it is derived from the
@@ -159,6 +190,22 @@ declare class RdxCheckboxRootDirective implements RdxFormCheckboxControl {
159
190
  /** @ignore The effective disabled state, including the group. */
160
191
  readonly disabledState: Signal<boolean>;
161
192
  readonly readOnlyState: Signal<boolean>;
193
+ private readonly dirtyValue;
194
+ /** @ignore Invalid when the `invalid` input is set or the `errors` list is non-empty. */
195
+ readonly invalidState: Signal<boolean>;
196
+ /** Tri-state display validity exposed by an enclosing Field; absent when standalone. */
197
+ private readonly fieldValidity;
198
+ /**
199
+ * @ignore Tri-state *displayed* validity. A **standalone** checkbox inside a `rdxFieldRoot` defers to
200
+ * the field's gated `validState` (so a field whose `validationMode` defers display (e.g. `onBlur`) stays neutral); inside a
201
+ * `rdxCheckboxGroup` the group owns the field relationship, so the item keeps its own binary validity
202
+ * (the field's invalid must not paint every checkbox red).
203
+ */
204
+ readonly displayValid: Signal<boolean | null>;
205
+ /** @ignore */
206
+ readonly touchedState: Signal<boolean>;
207
+ /** @ignore */
208
+ readonly dirtyState: Signal<boolean>;
162
209
  readonly state: Signal<"indeterminate" | "checked" | "unchecked">;
163
210
  constructor();
164
211
  toggle(event?: Event): void;
@@ -168,7 +215,7 @@ declare class RdxCheckboxRootDirective implements RdxFormCheckboxControl {
168
215
  private setOptionalAttribute;
169
216
  private setBooleanAttribute;
170
217
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxCheckboxRootDirective, never>;
171
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxCheckboxRootDirective, "[rdxCheckboxRoot]", never, { "checked": { "alias": "checked"; "required": false; "isSignal": true; }; "defaultChecked": { "alias": "defaultChecked"; "required": false; "isSignal": true; }; "indeterminate": { "alias": "indeterminate"; "required": false; "isSignal": true; }; "submitValue": { "alias": "value"; "required": false; "isSignal": true; }; "uncheckedValue": { "alias": "uncheckedValue"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readOnly"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "parent": { "alias": "parent"; "required": false; "isSignal": true; }; "form": { "alias": "form"; "required": false; "isSignal": true; }; }, { "checked": "checkedChange"; "indeterminate": "indeterminateChange"; "onCheckedChange": "onCheckedChange"; }, never, never, true, [{ directive: typeof _radix_ng_primitives_core.RdxControlValueAccessor; inputs: { "value": "checked"; "disabled": "disabled"; }; outputs: {}; }]>;
218
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxCheckboxRootDirective, "[rdxCheckboxRoot]", never, { "checked": { "alias": "checked"; "required": false; "isSignal": true; }; "defaultChecked": { "alias": "defaultChecked"; "required": false; "isSignal": true; }; "indeterminate": { "alias": "indeterminate"; "required": false; "isSignal": true; }; "submitValue": { "alias": "value"; "required": false; "isSignal": true; }; "uncheckedValue": { "alias": "uncheckedValue"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readOnly"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "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; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "parent": { "alias": "parent"; "required": false; "isSignal": true; }; "form": { "alias": "form"; "required": false; "isSignal": true; }; }, { "checked": "checkedChange"; "indeterminate": "indeterminateChange"; "touched": "touchedChange"; "onCheckedChange": "onCheckedChange"; "touch": "touch"; }, never, never, true, [{ directive: typeof _radix_ng_primitives_core.RdxControlValueAccessor; inputs: { "value": "checked"; "disabled": "disabled"; }; outputs: {}; }]>;
172
219
  }
173
220
 
174
221
  type RdxCheckboxGroupValueChangeReason = 'none';
@@ -207,7 +254,7 @@ declare const provideCheckboxGroupContext: (useFactory: () => RdxCheckboxGroupCo
207
254
  * Each child `rdxCheckboxRoot` participates by its `name`. A child marked `parent` becomes a
208
255
  * "select all" checkbox whose state is derived from `allValues`.
209
256
  */
210
- declare class RdxCheckboxGroupDirective implements ControlValueAccessor {
257
+ declare class RdxCheckboxGroupDirective extends RdxFormUiControlBase implements ControlValueAccessor, RdxFormValueControl<string[]> {
211
258
  /** The names of the currently checked checkboxes. Use with `onValueChange` or `[(value)]`. */
212
259
  readonly value: _angular_core.ModelSignal<string[]>;
213
260
  /** The names checked initially when the group is uncontrolled. */
@@ -242,6 +289,8 @@ declare class RdxCheckboxGroupDirective implements ControlValueAccessor {
242
289
  private onChange;
243
290
  onTouched: () => void;
244
291
  constructor();
292
+ /** @ignore Bridge the CVA `onTouched` so `markAsTouched()` also notifies Reactive/template forms. */
293
+ protected formUiTouchTarget(): RdxFormUiTouchTarget;
245
294
  /** @ignore Register a child's disabled signal keyed by its name. */
246
295
  registerChild(name: string, disabled: Signal<boolean>): () => void;
247
296
  /** A stable control id for a child, derived from the group id and the child name. */
@@ -273,7 +322,7 @@ declare class RdxCheckboxGroupDirective implements ControlValueAccessor {
273
322
  /** @ignore */
274
323
  setDisabledState(isDisabled: boolean): void;
275
324
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxCheckboxGroupDirective, never>;
276
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxCheckboxGroupDirective, "[rdxCheckboxGroup]", ["rdxCheckboxGroup"], { "value": { "alias": "value"; "required": false; "isSignal": true; }; "defaultValue": { "alias": "defaultValue"; "required": false; "isSignal": true; }; "allValues": { "alias": "allValues"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "onValueChange": "onValueChange"; }, never, never, true, never>;
325
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxCheckboxGroupDirective, "[rdxCheckboxGroup]", ["rdxCheckboxGroup"], { "value": { "alias": "value"; "required": false; "isSignal": true; }; "defaultValue": { "alias": "defaultValue"; "required": false; "isSignal": true; }; "allValues": { "alias": "allValues"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "onValueChange": "onValueChange"; }, never, never, true, [{ directive: typeof _radix_ng_primitives_core.RdxFormUiStateHost; inputs: {}; outputs: {}; }]>;
277
326
  }
278
327
 
279
328
  declare class RdxCheckboxIndicatorDirective {
@@ -3,7 +3,7 @@ import { Signal, Injector } from '@angular/core';
3
3
  import * as i1 from '@radix-ng/primitives/popper';
4
4
  import { RdxPopperContentWrapper } from '@radix-ng/primitives/popper';
5
5
  import * as _radix_ng_primitives_core from '@radix-ng/primitives/core';
6
- import { AcceptableValue, RdxCancelableChangeEventDetails, RdxFloatingRootContext, Direction, BooleanInput, ItemValueComparator } from '@radix-ng/primitives/core';
6
+ import { AcceptableValue, RdxCancelableChangeEventDetails, RdxFormUiControlBase, RdxFormValueControl, RdxFloatingRootContext, Direction, BooleanInput, ItemValueComparator, RdxFormUiTouchTarget } from '@radix-ng/primitives/core';
7
7
  import { ControlValueAccessor } from '@angular/forms';
8
8
  import * as _radix_ng_primitives_combobox from '@radix-ng/primitives/combobox';
9
9
  import * as i1$1 from '@radix-ng/primitives/dismissable-layer';
@@ -225,6 +225,9 @@ declare const context: () => {
225
225
  disabledState: _angular_core.Signal<boolean>;
226
226
  readonly: _angular_core.InputSignalWithTransform<boolean, unknown>;
227
227
  requiredState: _angular_core.Signal<boolean>;
228
+ invalidState: _angular_core.Signal<boolean>;
229
+ touchedState: _angular_core.Signal<boolean>;
230
+ dirtyState: _angular_core.Signal<boolean>;
228
231
  openOnInputClick: _angular_core.InputSignalWithTransform<boolean, unknown>;
229
232
  modal: _angular_core.InputSignalWithTransform<boolean, unknown>;
230
233
  virtualized: _angular_core.InputSignalWithTransform<boolean, unknown>;
@@ -297,6 +300,9 @@ declare const injectComboboxRootContext: _radix_ng_primitives_core.InjectContext
297
300
  disabledState: _angular_core.Signal<boolean>;
298
301
  readonly: _angular_core.InputSignalWithTransform<boolean, unknown>;
299
302
  requiredState: _angular_core.Signal<boolean>;
303
+ invalidState: _angular_core.Signal<boolean>;
304
+ touchedState: _angular_core.Signal<boolean>;
305
+ dirtyState: _angular_core.Signal<boolean>;
300
306
  openOnInputClick: _angular_core.InputSignalWithTransform<boolean, unknown>;
301
307
  modal: _angular_core.InputSignalWithTransform<boolean, unknown>;
302
308
  virtualized: _angular_core.InputSignalWithTransform<boolean, unknown>;
@@ -368,6 +374,9 @@ declare const provideComboboxRootContext: (useFactory: () => {
368
374
  disabledState: _angular_core.Signal<boolean>;
369
375
  readonly: _angular_core.InputSignalWithTransform<boolean, unknown>;
370
376
  requiredState: _angular_core.Signal<boolean>;
377
+ invalidState: _angular_core.Signal<boolean>;
378
+ touchedState: _angular_core.Signal<boolean>;
379
+ dirtyState: _angular_core.Signal<boolean>;
371
380
  openOnInputClick: _angular_core.InputSignalWithTransform<boolean, unknown>;
372
381
  modal: _angular_core.InputSignalWithTransform<boolean, unknown>;
373
382
  virtualized: _angular_core.InputSignalWithTransform<boolean, unknown>;
@@ -433,7 +442,7 @@ declare const provideComboboxRootContext: (useFactory: () => {
433
442
  *
434
443
  * @group Components
435
444
  */
436
- declare class RdxComboboxRoot implements ControlValueAccessor {
445
+ declare class RdxComboboxRoot extends RdxFormUiControlBase implements ControlValueAccessor, RdxFormValueControl<ComboboxValue | null> {
437
446
  private readonly injector;
438
447
  /** Per-popup floating root context (ADR 0015) — `open` / `triggers` / reference for the dismissal engine. */
439
448
  readonly floatingContext: RdxFloatingRootContext;
@@ -546,6 +555,12 @@ declare class RdxComboboxRoot implements ControlValueAccessor {
546
555
  private readonly cvaDisabled;
547
556
  readonly disabledState: _angular_core.Signal<boolean>;
548
557
  readonly requiredState: _angular_core.Signal<boolean>;
558
+ /** @ignore */
559
+ readonly invalidState: _angular_core.Signal<boolean>;
560
+ /** @ignore */
561
+ readonly touchedState: _angular_core.Signal<boolean>;
562
+ /** @ignore */
563
+ readonly dirtyState: _angular_core.Signal<boolean>;
549
564
  private readonly preventUnmountOnClose;
550
565
  readonly present: _angular_core.Signal<boolean>;
551
566
  /**
@@ -617,6 +632,8 @@ declare class RdxComboboxRoot implements ControlValueAccessor {
617
632
  registerChipsNav(fn: (() => boolean) | null): void;
618
633
  /** Moves focus to the last chip, if any. Returns whether a chip was focused. */
619
634
  focusLastChip(): boolean;
635
+ /** @ignore Bridge the CVA `onTouched` so `markAsTouched()` also notifies Reactive/template forms. */
636
+ protected formUiTouchTarget(): RdxFormUiTouchTarget;
620
637
  markAsTouched(): void;
621
638
  /**
622
639
  * The single guarded value-mutation point for all user-driven changes (selection toggle, Clear,
@@ -669,6 +686,9 @@ declare class RdxComboboxInput {
669
686
  disabledState: _angular_core.Signal<boolean>;
670
687
  readonly: _angular_core.InputSignalWithTransform<boolean, unknown>;
671
688
  requiredState: _angular_core.Signal<boolean>;
689
+ invalidState: _angular_core.Signal<boolean>;
690
+ touchedState: _angular_core.Signal<boolean>;
691
+ dirtyState: _angular_core.Signal<boolean>;
672
692
  openOnInputClick: _angular_core.InputSignalWithTransform<boolean, unknown>;
673
693
  modal: _angular_core.InputSignalWithTransform<boolean, unknown>;
674
694
  virtualized: _angular_core.InputSignalWithTransform<boolean, unknown>;
@@ -733,8 +753,16 @@ declare class RdxComboboxInput {
733
753
  /** Marks the input as invalid independently of any Field state. */
734
754
  readonly invalid: _angular_core.InputSignalWithTransform<boolean, BooleanInput>;
735
755
  protected readonly invalidState: _angular_core.Signal<boolean>;
756
+ /**
757
+ * Tri-state *displayed* validity: the enclosing Field's gated `validState` when inside a `rdxFieldRoot`
758
+ * (so a field whose `validationMode` defers display (e.g. `onBlur`) keeps the input neutral until revealed), else the input's
759
+ * own binary invalidity.
760
+ */
761
+ protected readonly displayValid: _angular_core.Signal<boolean | null>;
736
762
  protected readonly disabledState: _angular_core.Signal<boolean>;
737
763
  protected readonly requiredState: _angular_core.Signal<boolean>;
764
+ protected readonly touchedState: _angular_core.Signal<boolean>;
765
+ protected readonly dirtyState: _angular_core.Signal<boolean>;
738
766
  protected readonly filledState: _angular_core.Signal<boolean>;
739
767
  protected readonly focusedState: _angular_core.Signal<boolean>;
740
768
  protected readonly isEmptyValue: _angular_core.Signal<boolean>;
@@ -780,6 +808,9 @@ declare class RdxComboboxInputGroup {
780
808
  disabledState: _angular_core.Signal<boolean>;
781
809
  readonly: _angular_core.InputSignalWithTransform<boolean, unknown>;
782
810
  requiredState: _angular_core.Signal<boolean>;
811
+ invalidState: _angular_core.Signal<boolean>;
812
+ touchedState: _angular_core.Signal<boolean>;
813
+ dirtyState: _angular_core.Signal<boolean>;
783
814
  openOnInputClick: _angular_core.InputSignalWithTransform<boolean, unknown>;
784
815
  modal: _angular_core.InputSignalWithTransform<boolean, unknown>;
785
816
  virtualized: _angular_core.InputSignalWithTransform<boolean, unknown>;
@@ -897,6 +928,9 @@ declare class RdxComboboxTrigger {
897
928
  disabledState: _angular_core.Signal<boolean>;
898
929
  readonly: _angular_core.InputSignalWithTransform<boolean, unknown>;
899
930
  requiredState: _angular_core.Signal<boolean>;
931
+ invalidState: _angular_core.Signal<boolean>;
932
+ touchedState: _angular_core.Signal<boolean>;
933
+ dirtyState: _angular_core.Signal<boolean>;
900
934
  openOnInputClick: _angular_core.InputSignalWithTransform<boolean, unknown>;
901
935
  modal: _angular_core.InputSignalWithTransform<boolean, unknown>;
902
936
  virtualized: _angular_core.InputSignalWithTransform<boolean, unknown>;
@@ -995,6 +1029,9 @@ declare class RdxComboboxClear {
995
1029
  disabledState: _angular_core.Signal<boolean>;
996
1030
  readonly: _angular_core.InputSignalWithTransform<boolean, unknown>;
997
1031
  requiredState: _angular_core.Signal<boolean>;
1032
+ invalidState: _angular_core.Signal<boolean>;
1033
+ touchedState: _angular_core.Signal<boolean>;
1034
+ dirtyState: _angular_core.Signal<boolean>;
998
1035
  openOnInputClick: _angular_core.InputSignalWithTransform<boolean, unknown>;
999
1036
  modal: _angular_core.InputSignalWithTransform<boolean, unknown>;
1000
1037
  virtualized: _angular_core.InputSignalWithTransform<boolean, unknown>;
@@ -1122,6 +1159,9 @@ declare class RdxComboboxBackdrop {
1122
1159
  disabledState: _angular_core.Signal<boolean>;
1123
1160
  readonly: _angular_core.InputSignalWithTransform<boolean, unknown>;
1124
1161
  requiredState: _angular_core.Signal<boolean>;
1162
+ invalidState: _angular_core.Signal<boolean>;
1163
+ touchedState: _angular_core.Signal<boolean>;
1164
+ dirtyState: _angular_core.Signal<boolean>;
1125
1165
  openOnInputClick: _angular_core.InputSignalWithTransform<boolean, unknown>;
1126
1166
  modal: _angular_core.InputSignalWithTransform<boolean, unknown>;
1127
1167
  virtualized: _angular_core.InputSignalWithTransform<boolean, unknown>;
@@ -1221,6 +1261,9 @@ declare class RdxComboboxPopup {
1221
1261
  disabledState: _angular_core.Signal<boolean>;
1222
1262
  readonly: _angular_core.InputSignalWithTransform<boolean, unknown>;
1223
1263
  requiredState: _angular_core.Signal<boolean>;
1264
+ invalidState: _angular_core.Signal<boolean>;
1265
+ touchedState: _angular_core.Signal<boolean>;
1266
+ dirtyState: _angular_core.Signal<boolean>;
1224
1267
  openOnInputClick: _angular_core.InputSignalWithTransform<boolean, unknown>;
1225
1268
  modal: _angular_core.InputSignalWithTransform<boolean, unknown>;
1226
1269
  virtualized: _angular_core.InputSignalWithTransform<boolean, unknown>;
@@ -1327,6 +1370,9 @@ declare class RdxComboboxList {
1327
1370
  disabledState: _angular_core.Signal<boolean>;
1328
1371
  readonly: _angular_core.InputSignalWithTransform<boolean, unknown>;
1329
1372
  requiredState: _angular_core.Signal<boolean>;
1373
+ invalidState: _angular_core.Signal<boolean>;
1374
+ touchedState: _angular_core.Signal<boolean>;
1375
+ dirtyState: _angular_core.Signal<boolean>;
1330
1376
  openOnInputClick: _angular_core.InputSignalWithTransform<boolean, unknown>;
1331
1377
  modal: _angular_core.InputSignalWithTransform<boolean, unknown>;
1332
1378
  virtualized: _angular_core.InputSignalWithTransform<boolean, unknown>;
@@ -1574,6 +1620,9 @@ declare class RdxComboboxEmpty {
1574
1620
  disabledState: _angular_core.Signal<boolean>;
1575
1621
  readonly: _angular_core.InputSignalWithTransform<boolean, unknown>;
1576
1622
  requiredState: _angular_core.Signal<boolean>;
1623
+ invalidState: _angular_core.Signal<boolean>;
1624
+ touchedState: _angular_core.Signal<boolean>;
1625
+ dirtyState: _angular_core.Signal<boolean>;
1577
1626
  openOnInputClick: _angular_core.InputSignalWithTransform<boolean, unknown>;
1578
1627
  modal: _angular_core.InputSignalWithTransform<boolean, unknown>;
1579
1628
  virtualized: _angular_core.InputSignalWithTransform<boolean, unknown>;