@radix-ng/primitives 1.0.0-beta.5 → 1.0.2

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 (62) hide show
  1. package/composite/README.md +3 -0
  2. package/fesm2022/radix-ng-primitives-accordion.mjs +20 -44
  3. package/fesm2022/radix-ng-primitives-accordion.mjs.map +1 -1
  4. package/fesm2022/radix-ng-primitives-checkbox.mjs +134 -58
  5. package/fesm2022/radix-ng-primitives-checkbox.mjs.map +1 -1
  6. package/fesm2022/radix-ng-primitives-composite.mjs +599 -0
  7. package/fesm2022/radix-ng-primitives-composite.mjs.map +1 -0
  8. package/fesm2022/radix-ng-primitives-drawer.mjs +442 -2
  9. package/fesm2022/radix-ng-primitives-drawer.mjs.map +1 -1
  10. package/fesm2022/radix-ng-primitives-menu.mjs +315 -68
  11. package/fesm2022/radix-ng-primitives-menu.mjs.map +1 -1
  12. package/fesm2022/radix-ng-primitives-menubar.mjs +91 -36
  13. package/fesm2022/radix-ng-primitives-menubar.mjs.map +1 -1
  14. package/fesm2022/radix-ng-primitives-navigation-menu.mjs +281 -88
  15. package/fesm2022/radix-ng-primitives-navigation-menu.mjs.map +1 -1
  16. package/fesm2022/radix-ng-primitives-popover.mjs +40 -15
  17. package/fesm2022/radix-ng-primitives-popover.mjs.map +1 -1
  18. package/fesm2022/radix-ng-primitives-popper.mjs +73 -65
  19. package/fesm2022/radix-ng-primitives-popper.mjs.map +1 -1
  20. package/fesm2022/radix-ng-primitives-radio.mjs +63 -27
  21. package/fesm2022/radix-ng-primitives-radio.mjs.map +1 -1
  22. package/fesm2022/radix-ng-primitives-scroll-area.mjs +56 -25
  23. package/fesm2022/radix-ng-primitives-scroll-area.mjs.map +1 -1
  24. package/fesm2022/radix-ng-primitives-select.mjs +59 -29
  25. package/fesm2022/radix-ng-primitives-select.mjs.map +1 -1
  26. package/fesm2022/radix-ng-primitives-slider.mjs +57 -13
  27. package/fesm2022/radix-ng-primitives-slider.mjs.map +1 -1
  28. package/fesm2022/radix-ng-primitives-tabs.mjs +335 -73
  29. package/fesm2022/radix-ng-primitives-tabs.mjs.map +1 -1
  30. package/fesm2022/radix-ng-primitives-toggle-group.mjs +66 -21
  31. package/fesm2022/radix-ng-primitives-toggle-group.mjs.map +1 -1
  32. package/fesm2022/radix-ng-primitives-toggle.mjs +29 -11
  33. package/fesm2022/radix-ng-primitives-toggle.mjs.map +1 -1
  34. package/fesm2022/radix-ng-primitives-toolbar.mjs +68 -36
  35. package/fesm2022/radix-ng-primitives-toolbar.mjs.map +1 -1
  36. package/navigation-menu/README.md +5 -2
  37. package/package.json +6 -10
  38. package/types/radix-ng-primitives-accordion.d.ts +12 -16
  39. package/types/radix-ng-primitives-checkbox.d.ts +98 -70
  40. package/types/radix-ng-primitives-composite.d.ts +195 -0
  41. package/types/radix-ng-primitives-drawer.d.ts +40 -2
  42. package/types/radix-ng-primitives-menu.d.ts +46 -16
  43. package/types/radix-ng-primitives-menubar.d.ts +12 -5
  44. package/types/radix-ng-primitives-navigation-menu.d.ts +65 -33
  45. package/types/radix-ng-primitives-popover.d.ts +9 -5
  46. package/types/radix-ng-primitives-popper.d.ts +1 -0
  47. package/types/radix-ng-primitives-radio.d.ts +11 -9
  48. package/types/radix-ng-primitives-scroll-area.d.ts +4 -1
  49. package/types/radix-ng-primitives-select.d.ts +46 -32
  50. package/types/radix-ng-primitives-slider.d.ts +19 -4
  51. package/types/radix-ng-primitives-tabs.d.ts +69 -14
  52. package/types/radix-ng-primitives-toggle-group.d.ts +27 -16
  53. package/types/radix-ng-primitives-toggle.d.ts +5 -5
  54. package/types/radix-ng-primitives-toolbar.d.ts +84 -69
  55. package/collection/README.md +0 -1
  56. package/fesm2022/radix-ng-primitives-collection.mjs +0 -72
  57. package/fesm2022/radix-ng-primitives-collection.mjs.map +0 -1
  58. package/fesm2022/radix-ng-primitives-roving-focus.mjs +0 -388
  59. package/fesm2022/radix-ng-primitives-roving-focus.mjs.map +0 -1
  60. package/roving-focus/README.md +0 -3
  61. package/types/radix-ng-primitives-collection.d.ts +0 -44
  62. package/types/radix-ng-primitives-roving-focus.d.ts +0 -187
@@ -3,6 +3,7 @@ import { Signal } from '@angular/core';
3
3
  import * as _radix_ng_primitives_core from '@radix-ng/primitives/core';
4
4
  import { RdxControlValueAccessor, NumberInput, BooleanInput, RdxCancelableChangeEventDetails } from '@radix-ng/primitives/core';
5
5
  export { clamp } from '@radix-ng/primitives/core';
6
+ import * as i1 from '@radix-ng/primitives/composite';
6
7
  import * as _radix_ng_primitives_slider from '@radix-ng/primitives/slider';
7
8
 
8
9
  type SliderOrientation = 'horizontal' | 'vertical';
@@ -120,6 +121,9 @@ interface RdxSliderThumbRef {
120
121
  /** Whether this thumb is disabled (own state OR root disabled). */
121
122
  readonly disabled: Signal<boolean>;
122
123
  }
124
+ interface RdxSliderThumbMetadata {
125
+ inputId?: string | undefined;
126
+ }
123
127
  /**
124
128
  * Groups all parts of the slider and owns its state, value-change logic and
125
129
  * thumb registration. A single directive drives both orientations — there are no
@@ -131,6 +135,7 @@ declare class RdxSliderRoot {
131
135
  /** @ignore */
132
136
  protected readonly cva: RdxControlValueAccessor<SliderValue>;
133
137
  private readonly document;
138
+ private readonly compositeList;
134
139
  readonly id: _angular_core.InputSignal<string>;
135
140
  /**
136
141
  * The minimum value of the slider.
@@ -239,6 +244,8 @@ declare class RdxSliderRoot {
239
244
  private readonly thumbs;
240
245
  /** Registered thumbs in DOM order. */
241
246
  readonly thumbList: Signal<RdxSliderThumbRef[]>;
247
+ /** Input ids registered by thumbs, in DOM order. */
248
+ readonly thumbInputIds: Signal<string[]>;
242
249
  /** @ignore */
243
250
  registerThumb(thumb: RdxSliderThumbRef): void;
244
251
  /** @ignore */
@@ -274,7 +281,7 @@ declare class RdxSliderRoot {
274
281
  /** @ignore */
275
282
  getOwnerWindow(): Window | undefined;
276
283
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxSliderRoot, never>;
277
- 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 _radix_ng_primitives_core.RdxControlValueAccessor; inputs: { "value": "value"; "disabled": "disabled"; }; outputs: {}; }]>;
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: {}; }]>;
278
285
  }
279
286
 
280
287
  /**
@@ -346,9 +353,11 @@ declare class RdxSliderIndicator {
346
353
  */
347
354
  declare class RdxSliderThumb implements RdxSliderThumbRef {
348
355
  protected readonly root: _radix_ng_primitives_slider.RdxSliderRoot;
356
+ private readonly listItem;
349
357
  readonly element: HTMLElement;
350
358
  /** The nested range input, set by `[rdxSliderThumbInput]`. */
351
359
  inputElement: HTMLInputElement | null;
360
+ private readonly inputId;
352
361
  /** Explicit index for this thumb (required for SSR range sliders). */
353
362
  readonly indexInput: _angular_core.InputSignalWithTransform<number | undefined, NumberInput>;
354
363
  /** Disables this individual thumb. */
@@ -365,8 +374,12 @@ declare class RdxSliderThumb implements RdxSliderThumbRef {
365
374
  constructor();
366
375
  private updateInsetPosition;
367
376
  protected onPointerDown(event: PointerEvent): void;
377
+ /** @ignore */
378
+ setInputElement(input: HTMLInputElement, id: string): void;
379
+ /** @ignore */
380
+ clearInputElement(input: HTMLInputElement): void;
368
381
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxSliderThumb, never>;
369
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxSliderThumb, "div[rdxSliderThumb]", ["rdxSliderThumb"], { "indexInput": { "alias": "index"; "required": false; "isSignal": true; }; "thumbDisabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
382
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxSliderThumb, "div[rdxSliderThumb]", ["rdxSliderThumb"], { "indexInput": { "alias": "index"; "required": false; "isSignal": true; }; "thumbDisabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1.RdxCompositeListItem; inputs: {}; outputs: {}; }]>;
370
383
  }
371
384
 
372
385
  /**
@@ -380,6 +393,7 @@ declare class RdxSliderThumbInput {
380
393
  protected readonly root: _radix_ng_primitives_slider.RdxSliderRoot;
381
394
  protected readonly thumb: RdxSliderThumb;
382
395
  private readonly element;
396
+ readonly id: _angular_core.InputSignal<string>;
383
397
  readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
384
398
  readonly ariaValueTextInput: _angular_core.InputSignal<string | undefined>;
385
399
  protected readonly writingMode: _angular_core.Signal<"vertical-rl" | "vertical-lr" | undefined>;
@@ -391,7 +405,7 @@ declare class RdxSliderThumbInput {
391
405
  protected onBlur(): void;
392
406
  protected onKeyDown(event: KeyboardEvent): void;
393
407
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxSliderThumbInput, never>;
394
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxSliderThumbInput, "input[rdxSliderThumbInput]", ["rdxSliderThumbInput"], { "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; "ariaValueTextInput": { "alias": "aria-valuetext"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
408
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxSliderThumbInput, "input[rdxSliderThumbInput]", ["rdxSliderThumbInput"], { "id": { "alias": "id"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; "ariaValueTextInput": { "alias": "aria-valuetext"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
395
409
  }
396
410
 
397
411
  /**
@@ -404,6 +418,7 @@ declare class RdxSliderValue {
404
418
  protected readonly root: _radix_ng_primitives_slider.RdxSliderRoot;
405
419
  /** The separator placed between values of a range slider. */
406
420
  readonly separator: _angular_core.InputSignal<string>;
421
+ protected readonly forAttr: _angular_core.Signal<string | undefined>;
407
422
  protected readonly display: _angular_core.Signal<string>;
408
423
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxSliderValue, never>;
409
424
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxSliderValue, "output[rdxSliderValue]", ["rdxSliderValue"], { "separator": { "alias": "separator"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
@@ -426,4 +441,4 @@ declare class RdxSliderModule {
426
441
  }
427
442
 
428
443
  export { ALL_KEYS, ARROW_KEYS, COMPOSITE_KEYS, RdxSliderControl, RdxSliderIndicator, RdxSliderModule, RdxSliderRoot, RdxSliderThumb, RdxSliderThumbInput, RdxSliderTrack, RdxSliderValue, areValuesEqual, asc, formatNumber, getControlOffset, getDecimalPrecision, getDefaultAriaValueText, getInsetThumbPositionPercent, getMidpoint, getNewValue, getPushedThumbValues, getSliderValue, injectSliderRootContext, provideSliderRootContext, replaceArrayItemAtIndex, resolveThumbCollision, roundValueToStep, validateMinimumDistance, valueArrayToPercentages, valueToPercent };
429
- export type { RdxSliderThumbAlignment, RdxSliderThumbRef, RdxSliderValueChangeEvent, RdxSliderValueChangeEventDetails, RdxSliderValueChangeReason, RdxSliderValueCommitEvent, RdxSliderValueCommitEventDetails, RdxSliderValueCommitReason, ResolveThumbCollisionParams, ResolveThumbCollisionResult, SliderOrientation, SliderValue, ThumbCollisionBehavior };
444
+ export type { RdxSliderThumbAlignment, RdxSliderThumbMetadata, RdxSliderThumbRef, RdxSliderValueChangeEvent, RdxSliderValueChangeEventDetails, RdxSliderValueChangeReason, RdxSliderValueCommitEvent, RdxSliderValueCommitEventDetails, RdxSliderValueCommitReason, ResolveThumbCollisionParams, ResolveThumbCollisionResult, SliderOrientation, SliderValue, ThumbCollisionBehavior };
@@ -1,10 +1,11 @@
1
1
  import * as _angular_core from '@angular/core';
2
2
  import { Signal } from '@angular/core';
3
3
  import * as i1 from '@radix-ng/primitives/presence';
4
+ import * as i1$1 from '@radix-ng/primitives/composite';
5
+ import { RdxCompositeMetadata } from '@radix-ng/primitives/composite';
4
6
  import * as _radix_ng_primitives_core from '@radix-ng/primitives/core';
5
7
  import { DataOrientation, RdxCancelableChangeEventDetails, BooleanInput } from '@radix-ng/primitives/core';
6
8
  import * as _radix_ng_primitives_tabs from '@radix-ng/primitives/tabs';
7
- import * as i1$1 from '@radix-ng/primitives/roving-focus';
8
9
 
9
10
  /**
10
11
  * Structural directive that mounts the tab panel contents only while the panel is active,
@@ -27,9 +28,18 @@ declare class RdxTabsPanelPresence {
27
28
  type RdxTabsActivationDirection = 'left' | 'right' | 'up' | 'down' | 'none';
28
29
  /** A value that identifies a tab / panel pair. */
29
30
  type RdxTabsValue = string | number | null;
31
+ /** Metadata registered for each tab in the composite list. */
32
+ interface RdxTabsTabMetadata {
33
+ [key: string]: unknown;
34
+ disabled: boolean;
35
+ id: string;
36
+ value: RdxTabsValue;
37
+ }
30
38
 
31
- type RdxTabsValueChangeReason = 'trigger-press' | 'keyboard' | 'focus' | 'none';
32
- type RdxTabsValueChangeEventDetails = RdxCancelableChangeEventDetails<RdxTabsValueChangeReason>;
39
+ type RdxTabsValueChangeReason = 'none' | 'disabled' | 'missing' | 'initial';
40
+ type RdxTabsValueChangeEventDetails = RdxCancelableChangeEventDetails<RdxTabsValueChangeReason> & {
41
+ activationDirection: RdxTabsActivationDirection;
42
+ };
33
43
  interface RdxTabsValueChangeEvent {
34
44
  value: RdxTabsValue;
35
45
  eventDetails: RdxTabsValueChangeEventDetails;
@@ -48,6 +58,9 @@ declare class RdxTabsRoot {
48
58
  readonly value: _angular_core.ModelSignal<RdxTabsValue | undefined>;
49
59
  /**
50
60
  * The value of the tab that should be initially selected when uncontrolled.
61
+ * When omitted, Base UI parity uses `0` as the implicit default and falls back to the first enabled tab.
62
+ *
63
+ * @default 0
51
64
  */
52
65
  readonly defaultValue: _angular_core.InputSignal<RdxTabsValue | undefined>;
53
66
  /**
@@ -59,20 +72,38 @@ declare class RdxTabsRoot {
59
72
  readonly orientation: _angular_core.InputSignal<DataOrientation>;
60
73
  /**
61
74
  * Event emitted when the selected tab changes.
75
+ *
76
+ * `eventDetails.reason` is `'none'` for user-initiated changes, `'initial'` for the first automatic
77
+ * uncontrolled selection, `'disabled'` when an uncontrolled selection falls back from a disabled tab,
78
+ * and `'missing'` when it falls back from a removed tab. Automatic changes are not cancelable.
62
79
  */
63
80
  readonly onValueChange: _angular_core.OutputEmitterRef<RdxTabsValueChangeEvent>;
64
81
  /** @ignore Set by `[rdxTabsList]`. */
65
82
  readonly activateOnFocus: _angular_core.WritableSignal<boolean>;
66
83
  /** @ignore Set by `[rdxTabsList]`. */
67
84
  readonly tabListElement: _angular_core.WritableSignal<HTMLElement | null>;
85
+ /** @ignore Set by `[rdxTabsList]`. */
86
+ readonly tabMap: _angular_core.WritableSignal<Map<HTMLElement, RdxCompositeMetadata<RdxTabsTabMetadata>>>;
68
87
  /** @ignore */
69
88
  readonly activationDirection: _angular_core.WritableSignal<RdxTabsActivationDirection>;
89
+ private readonly externallyControlled;
90
+ private hasObservedValue;
91
+ private previousObservedValue;
92
+ private internalValueCommit;
93
+ private hasAppliedDefaultValue;
94
+ private initialDefaultValue;
95
+ private shouldNotifyInitialValueChange;
96
+ private shouldHonorDisabledDefaultValue;
97
+ private didRegisterTabs;
98
+ private lastKnownTabElement;
70
99
  constructor();
71
100
  /** @ignore */
72
101
  setValue(value: RdxTabsValue, event?: Event, reason?: RdxTabsValueChangeReason): void;
73
- private computeDirection;
102
+ private commitValue;
103
+ private commitAutomaticValueChange;
104
+ private notifyAutomaticValueChange;
74
105
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxTabsRoot, never>;
75
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxTabsRoot, "[rdxTabsRoot]", ["rdxTabsRoot"], { "value": { "alias": "value"; "required": false; "isSignal": true; }; "defaultValue": { "alias": "defaultValue"; "required": false; "isSignal": true; }; "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "onValueChange": "onValueChange"; }, never, never, true, never>;
106
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxTabsRoot, "[rdxTabsRoot]", ["rdxTabsRoot"], { "value": { "alias": "value"; "required": false; "isSignal": true; }; "defaultValue": { "alias": "defaultValue"; "required": false; "isSignal": true; }; "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "onValueChange": "onValueChange"; }, never, never, true, [{ directive: typeof i1$1.RdxCompositeList; inputs: {}; outputs: {}; }]>;
76
107
  }
77
108
 
78
109
  /**
@@ -83,7 +114,7 @@ declare class RdxTabsRoot {
83
114
  declare class RdxTabsList {
84
115
  protected readonly rootContext: _radix_ng_primitives_tabs.RdxTabsRootContext;
85
116
  private readonly elementRef;
86
- private readonly rovingFocusGroup;
117
+ private readonly compositeRoot;
87
118
  /**
88
119
  * Whether a tab is activated when it receives focus (automatic activation).
89
120
  * When `false`, tabs are only activated on click or Enter/Space.
@@ -97,9 +128,13 @@ declare class RdxTabsList {
97
128
  * @default true
98
129
  */
99
130
  readonly loopFocus: _angular_core.InputSignalWithTransform<boolean, unknown>;
131
+ private readonly tabMap;
132
+ private readonly tabMetadata;
133
+ private readonly disabledIndices;
134
+ private readonly activeIndex;
100
135
  constructor();
101
136
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxTabsList, never>;
102
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxTabsList, "[rdxTabsList]", ["rdxTabsList"], { "activateOnFocus": { "alias": "activateOnFocus"; "required": false; "isSignal": true; }; "loopFocus": { "alias": "loopFocus"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1$1.RdxRovingFocusGroupDirective; inputs: {}; outputs: {}; }]>;
137
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxTabsList, "[rdxTabsList]", ["rdxTabsList"], { "activateOnFocus": { "alias": "activateOnFocus"; "required": false; "isSignal": true; }; "loopFocus": { "alias": "loopFocus"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1$1.RdxCompositeRoot; inputs: {}; outputs: {}; }]>;
103
138
  }
104
139
 
105
140
  /**
@@ -109,30 +144,45 @@ declare class RdxTabsList {
109
144
  */
110
145
  declare class RdxTabsTab {
111
146
  protected readonly rootContext: _radix_ng_primitives_tabs.RdxTabsRootContext;
112
- private readonly rovingFocusItem;
147
+ private readonly compositeItem;
113
148
  /**
114
149
  * A unique value that associates the tab with a panel.
115
150
  */
116
151
  readonly value: _angular_core.InputSignal<RdxTabsValue>;
117
152
  /**
118
153
  * When `true`, prevents the user from interacting with the tab.
154
+ * Disabled tabs remain focusable during composite keyboard navigation, matching Base UI.
119
155
  */
120
156
  readonly disabled: _angular_core.InputSignalWithTransform<boolean, BooleanInput>;
157
+ /**
158
+ * Whether the host element is a native button. When `true`, `type="button"` is applied.
159
+ *
160
+ * @default true
161
+ */
162
+ readonly nativeButton: _angular_core.InputSignalWithTransform<boolean, BooleanInput>;
163
+ /**
164
+ * Optional id for the tab element. When omitted, an id is derived from the root id and tab value.
165
+ */
166
+ readonly id: _angular_core.InputSignal<string | undefined>;
121
167
  /** @ignore */
122
168
  protected readonly tabId: _angular_core.Signal<string>;
123
169
  /** @ignore */
124
170
  protected readonly panelId: _angular_core.Signal<string>;
125
171
  /** @ignore */
126
172
  protected readonly active: _angular_core.Signal<boolean>;
173
+ private isPressing;
174
+ private isMainButton;
127
175
  constructor();
128
176
  /** @ignore */
129
- protected onMouseDown(event: MouseEvent): void;
177
+ protected onClick(event: MouseEvent): void;
130
178
  /** @ignore */
131
179
  protected onKeyDown(event: KeyboardEvent): void;
132
180
  /** @ignore */
181
+ protected onPointerDown(event: PointerEvent): void;
182
+ /** @ignore */
133
183
  protected onFocus(event: FocusEvent): void;
134
184
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxTabsTab, never>;
135
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxTabsTab, "[rdxTabsTab]", ["rdxTabsTab"], { "value": { "alias": "value"; "required": true; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1$1.RdxRovingFocusItemDirective; inputs: { "allowShiftKey": "allowShiftKey"; }; outputs: {}; }]>;
185
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxTabsTab, "[rdxTabsTab]", ["rdxTabsTab"], { "value": { "alias": "value"; "required": true; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "nativeButton": { "alias": "nativeButton"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1$1.RdxCompositeItem; inputs: {}; outputs: {}; }]>;
136
186
  }
137
187
 
138
188
  /**
@@ -146,6 +196,7 @@ declare class RdxTabsTab {
146
196
  */
147
197
  declare class RdxTabsPanel {
148
198
  private readonly elementRef;
199
+ private readonly listItem;
149
200
  protected readonly rootContext: _radix_ng_primitives_tabs.RdxTabsRootContext;
150
201
  /**
151
202
  * A unique value that associates the panel with a tab.
@@ -181,15 +232,15 @@ declare class RdxTabsPanel {
181
232
  * element renders nothing), unless `keepMounted` keeps the inactive contents around.
182
233
  */
183
234
  protected readonly hidden: _angular_core.Signal<boolean>;
184
- /** @ignore Index of the panel, derived from the order of its associated tab. */
185
- protected readonly index: _angular_core.Signal<number | null>;
235
+ /** @ignore Index of the panel in DOM order. */
236
+ protected readonly index: _angular_core.Signal<number>;
186
237
  private previousActive;
187
238
  private isFirstRun;
188
239
  constructor();
189
240
  /** @ignore Called by `RdxTabsPanelPresence` so the panel stops forcing `hidden`. */
190
241
  markHasPresence(): void;
191
242
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxTabsPanel, never>;
192
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxTabsPanel, "[rdxTabsPanel]", ["rdxTabsPanel"], { "value": { "alias": "value"; "required": true; "isSignal": true; }; "keepMounted": { "alias": "keepMounted"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
243
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxTabsPanel, "[rdxTabsPanel]", ["rdxTabsPanel"], { "value": { "alias": "value"; "required": true; "isSignal": true; }; "keepMounted": { "alias": "keepMounted"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1$1.RdxCompositeListItem; inputs: {}; outputs: {}; }]>;
193
244
  }
194
245
 
195
246
  interface TabGeometry {
@@ -232,12 +283,16 @@ interface RdxTabsRootContext {
232
283
  readonly activateOnFocus: Signal<boolean>;
233
284
  /** The `[rdxTabsList]` host element, used to resolve tab order and indicator geometry. */
234
285
  readonly tabListElement: Signal<HTMLElement | null>;
286
+ /** Registered tabs in DOM order. */
287
+ readonly tabMap: Signal<Map<HTMLElement, RdxCompositeMetadata<RdxTabsTabMetadata>>>;
235
288
  /** Select a tab by value. No-op when the value is unchanged. */
236
- setValue(value: RdxTabsValue, event?: Event, reason?: string): void;
289
+ setValue(value: RdxTabsValue, event?: Event, reason?: RdxTabsValueChangeReason): void;
237
290
  /** Mirror the list's `activateOnFocus` input onto the root context. */
238
291
  setActivateOnFocus(value: boolean): void;
239
292
  /** Register the list host element. */
240
293
  setTabListElement(element: HTMLElement | null): void;
294
+ /** Register the tab composite map. */
295
+ setTabMap(map: Map<HTMLElement, RdxCompositeMetadata<RdxTabsTabMetadata>>): void;
241
296
  }
242
297
  declare const injectTabsRootContext: _radix_ng_primitives_core.InjectContext<RdxTabsRootContext>;
243
298
  declare const provideTabsRootContext: (useFactory: () => RdxTabsRootContext) => _angular_core.Provider;
@@ -1,11 +1,11 @@
1
- import * as _radix_ng_primitives_core from '@radix-ng/primitives/core';
2
- import { DataOrientation, BooleanInput, RdxCancelableChangeEventDetails } from '@radix-ng/primitives/core';
3
1
  import * as _angular_core from '@angular/core';
4
2
  import { Signal } from '@angular/core';
5
- import * as i1 from '@radix-ng/primitives/roving-focus';
6
- import { Direction } from '@radix-ng/primitives/roving-focus';
3
+ import * as _radix_ng_primitives_core from '@radix-ng/primitives/core';
4
+ import { DataOrientation, RdxCancelableChangeEventDetails, BooleanInput, Direction } from '@radix-ng/primitives/core';
7
5
  import { ControlValueAccessor } from '@angular/forms';
6
+ import * as i1 from '@radix-ng/primitives/composite';
8
7
 
8
+ type RdxToggleGroupContextChangeReason = 'none';
9
9
  /**
10
10
  * Shared state a {@link RdxToggle} reads when it participates in a toggle group.
11
11
  */
@@ -14,17 +14,17 @@ interface RdxToggleGroupContext {
14
14
  readonly value: Signal<string[]>;
15
15
  /** Whether the whole group is disabled. */
16
16
  readonly disabled: Signal<boolean>;
17
- /** Whether more than one item can be pressed at a time. */
18
- readonly multiple: Signal<boolean>;
19
17
  /** The orientation of the group. */
20
18
  readonly orientation: Signal<DataOrientation>;
19
+ /** Whether the group value was initialized by `value` or `defaultValue`. */
20
+ readonly isValueInitialized: Signal<boolean>;
21
21
  /** Toggle the pressed state of `value` within the group. */
22
- toggle(value: string, event?: Event): void;
22
+ toggle(value: string, event?: Event, eventDetails?: RdxCancelableChangeEventDetails<RdxToggleGroupContextChangeReason>): void;
23
23
  }
24
24
  declare const injectToggleGroupContext: _radix_ng_primitives_core.InjectContext<RdxToggleGroupContext>;
25
25
  declare const provideToggleGroupContext: (useFactory: () => RdxToggleGroupContext) => _angular_core.Provider;
26
26
 
27
- type RdxToggleGroupValueChangeReason = 'trigger-press' | 'none';
27
+ type RdxToggleGroupValueChangeReason = 'none';
28
28
  type RdxToggleGroupValueChangeEventDetails = RdxCancelableChangeEventDetails<RdxToggleGroupValueChangeReason>;
29
29
  interface RdxToggleGroupValueChangeEvent {
30
30
  value: string[];
@@ -33,7 +33,7 @@ interface RdxToggleGroupValueChangeEvent {
33
33
  /** Builds the shared context a {@link RdxToggle} reads when it belongs to this group. */
34
34
  declare function toggleGroupContext(instance: RdxToggleGroupBase): RdxToggleGroupContext;
35
35
  /**
36
- * Shared state and behavior for the toggle group. Concrete directives add the roving-focus group
36
+ * Shared state and behavior for the toggle group. Concrete directives add the composite root
37
37
  * ({@link RdxToggleGroup}) or omit it when an ancestor already owns focus, e.g. a toolbar
38
38
  * ({@link RdxToggleGroupWithoutFocus}).
39
39
  */
@@ -67,14 +67,18 @@ declare abstract class RdxToggleGroupBase implements ControlValueAccessor {
67
67
  readonly onValueChange: _angular_core.OutputEmitterRef<RdxToggleGroupValueChangeEvent>;
68
68
  /** @ignore */
69
69
  readonly pressedValues: _angular_core.Signal<string[]>;
70
+ /** @ignore */
71
+ readonly isValueInitialized: _angular_core.Signal<boolean>;
70
72
  protected readonly accessorDisabled: _angular_core.WritableSignal<boolean>;
71
73
  /** @ignore */
72
74
  readonly isDisabled: _angular_core.Signal<boolean>;
73
75
  private onChange?;
74
76
  protected onTouched?: () => void;
75
77
  constructor();
78
+ /** @ignore Extra disabled state inherited from composite parents such as Toolbar. */
79
+ protected isExternallyDisabled(): boolean;
76
80
  /** @ignore */
77
- toggle(value: string, event?: Event): void;
81
+ toggle(value: string, event?: Event, eventDetails?: RdxToggleGroupValueChangeEventDetails): void;
78
82
  /** @ignore */
79
83
  writeValue(value: string[] | string | null): void;
80
84
  /** @ignore */
@@ -88,34 +92,41 @@ declare abstract class RdxToggleGroupBase implements ControlValueAccessor {
88
92
  }
89
93
 
90
94
  /**
91
- * A set of two-state buttons that can be toggled on or off. Owns roving keyboard focus over its
95
+ * A set of two-state buttons that can be toggled on or off. Owns composite keyboard focus over its
92
96
  * `[rdxToggle]` children.
93
97
  *
94
98
  * @see https://base-ui.com/react/components/toggle-group
95
99
  */
96
100
  declare class RdxToggleGroup extends RdxToggleGroupBase {
101
+ private readonly elementRef;
97
102
  /** Text direction for arrow-key navigation. */
98
103
  readonly dirInput: _angular_core.InputSignal<Direction | undefined>;
99
- readonly dir: _angular_core.Signal<_radix_ng_primitives_core.Direction>;
104
+ readonly dir: _angular_core.Signal<Direction>;
100
105
  /**
101
106
  * Whether keyboard navigation should loop from the last item back to the first.
102
107
  *
103
108
  * @default true
104
109
  */
105
110
  readonly loopFocus: _angular_core.InputSignalWithTransform<boolean, BooleanInput>;
106
- private readonly rovingFocusGroup;
111
+ private readonly compositeRoot;
112
+ private readonly itemMetadata;
113
+ private readonly disabledIndices;
114
+ private readonly activeIndex;
107
115
  constructor();
108
116
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxToggleGroup, never>;
109
- 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.RdxRovingFocusGroupDirective; inputs: {}; outputs: {}; }]>;
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: {}; }]>;
110
118
  }
111
119
 
112
120
  /**
113
- * A toggle group that does NOT create its own roving-focus group, for use inside a container that
121
+ * A toggle group that does NOT create its own composite root, for use inside a container that
114
122
  * already owns keyboard focus (e.g. a toolbar). The `[rdxToggle]` children register with the nearest
115
- * ancestor roving-focus group instead. Mirrors Base UI's behavior of skipping its composite root
123
+ * ancestor composite root instead. Mirrors Base UI's behavior of skipping its composite root
116
124
  * when nested in a toolbar.
117
125
  */
118
126
  declare class RdxToggleGroupWithoutFocus extends RdxToggleGroupBase {
127
+ private readonly toolbarRootContext;
128
+ private readonly toolbarGroupContext;
129
+ protected isExternallyDisabled(): boolean;
119
130
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxToggleGroupWithoutFocus, never>;
120
131
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxToggleGroupWithoutFocus, "[rdxToggleGroupWithoutFocus]", ["rdxToggleGroupWithoutFocus"], {}, {}, never, never, true, never>;
121
132
  }
@@ -1,9 +1,9 @@
1
1
  import * as _angular_core from '@angular/core';
2
2
  import { BooleanInput, RdxCancelableChangeEventDetails } from '@radix-ng/primitives/core';
3
- import * as i1 from '@radix-ng/primitives/roving-focus';
3
+ import * as i1 from '@radix-ng/primitives/composite';
4
4
  import * as i1$1 from '@radix-ng/primitives/visually-hidden';
5
5
 
6
- type RdxTogglePressedChangeReason = 'trigger-press' | 'none';
6
+ type RdxTogglePressedChangeReason = 'none';
7
7
  type RdxTogglePressedChangeEventDetails = RdxCancelableChangeEventDetails<RdxTogglePressedChangeReason>;
8
8
  interface RdxTogglePressedChangeEvent {
9
9
  pressed: boolean;
@@ -13,13 +13,13 @@ interface RdxTogglePressedChangeEvent {
13
13
  * A two-state button that can be either on (pressed) or off.
14
14
  *
15
15
  * Works standalone or as an item of a `[rdxToggleGroup]`: inside a group it derives its pressed
16
- * state from the group's value (matched by `value`) and participates in the group's roving focus.
16
+ * state from the group's value (matched by `value`) and participates in the group's composite focus.
17
17
  *
18
18
  * @see https://base-ui.com/react/components/toggle
19
19
  */
20
20
  declare class RdxToggle {
21
21
  private readonly group;
22
- private readonly rovingItem;
22
+ private readonly compositeItem;
23
23
  /**
24
24
  * A value identifying this toggle inside a `[rdxToggleGroup]`. Required when used in a group.
25
25
  */
@@ -60,7 +60,7 @@ declare class RdxToggle {
60
60
  /** @ignore */
61
61
  protected onKeyDown(event: KeyboardEvent): void;
62
62
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxToggle, never>;
63
- 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.RdxRovingFocusItemDirective; inputs: {}; outputs: {}; }]>;
63
+ 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
64
  }
65
65
 
66
66
  declare class RdxToggleVisuallyHiddenInputDirective {