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

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-checkbox.mjs +33 -18
  2. package/fesm2022/radix-ng-primitives-checkbox.mjs.map +1 -1
  3. package/fesm2022/radix-ng-primitives-core.mjs +7 -0
  4. package/fesm2022/radix-ng-primitives-core.mjs.map +1 -1
  5. package/fesm2022/radix-ng-primitives-dialog.mjs +54 -12
  6. package/fesm2022/radix-ng-primitives-dialog.mjs.map +1 -1
  7. package/fesm2022/radix-ng-primitives-editable.mjs +12 -7
  8. package/fesm2022/radix-ng-primitives-editable.mjs.map +1 -1
  9. package/fesm2022/radix-ng-primitives-floating-focus-manager.mjs +294 -8
  10. package/fesm2022/radix-ng-primitives-floating-focus-manager.mjs.map +1 -1
  11. package/fesm2022/radix-ng-primitives-focus-scope.mjs +9 -0
  12. package/fesm2022/radix-ng-primitives-focus-scope.mjs.map +1 -1
  13. package/fesm2022/radix-ng-primitives-menu.mjs +34 -5
  14. package/fesm2022/radix-ng-primitives-menu.mjs.map +1 -1
  15. package/fesm2022/radix-ng-primitives-number-field.mjs +7 -2
  16. package/fesm2022/radix-ng-primitives-number-field.mjs.map +1 -1
  17. package/fesm2022/radix-ng-primitives-popover.mjs +77 -20
  18. package/fesm2022/radix-ng-primitives-popover.mjs.map +1 -1
  19. package/fesm2022/radix-ng-primitives-radio.mjs +19 -14
  20. package/fesm2022/radix-ng-primitives-radio.mjs.map +1 -1
  21. package/fesm2022/radix-ng-primitives-select.mjs +59 -37
  22. package/fesm2022/radix-ng-primitives-select.mjs.map +1 -1
  23. package/fesm2022/radix-ng-primitives-slider.mjs +259 -28
  24. package/fesm2022/radix-ng-primitives-slider.mjs.map +1 -1
  25. package/fesm2022/radix-ng-primitives-stepper.mjs +11 -7
  26. package/fesm2022/radix-ng-primitives-stepper.mjs.map +1 -1
  27. package/fesm2022/radix-ng-primitives-switch.mjs +10 -5
  28. package/fesm2022/radix-ng-primitives-switch.mjs.map +1 -1
  29. package/fesm2022/radix-ng-primitives-tabs.mjs +15 -10
  30. package/fesm2022/radix-ng-primitives-tabs.mjs.map +1 -1
  31. package/fesm2022/radix-ng-primitives-toggle-group.mjs +9 -4
  32. package/fesm2022/radix-ng-primitives-toggle-group.mjs.map +1 -1
  33. package/fesm2022/radix-ng-primitives-toggle.mjs +12 -6
  34. package/fesm2022/radix-ng-primitives-toggle.mjs.map +1 -1
  35. package/fesm2022/radix-ng-primitives-tooltip.mjs +180 -35
  36. package/fesm2022/radix-ng-primitives-tooltip.mjs.map +1 -1
  37. package/package.json +1 -1
  38. package/types/radix-ng-primitives-checkbox.d.ts +27 -15
  39. package/types/radix-ng-primitives-core.d.ts +2 -0
  40. package/types/radix-ng-primitives-dialog.d.ts +13 -2
  41. package/types/radix-ng-primitives-editable.d.ts +11 -5
  42. package/types/radix-ng-primitives-floating-focus-manager.d.ts +113 -16
  43. package/types/radix-ng-primitives-menu.d.ts +8 -2
  44. package/types/radix-ng-primitives-number-field.d.ts +8 -3
  45. package/types/radix-ng-primitives-popover.d.ts +18 -6
  46. package/types/radix-ng-primitives-radio.d.ts +13 -6
  47. package/types/radix-ng-primitives-select.d.ts +16 -20
  48. package/types/radix-ng-primitives-slider.d.ts +60 -9
  49. package/types/radix-ng-primitives-stepper.d.ts +11 -4
  50. package/types/radix-ng-primitives-switch.d.ts +10 -4
  51. package/types/radix-ng-primitives-tabs.d.ts +12 -6
  52. package/types/radix-ng-primitives-toggle-group.d.ts +11 -5
  53. package/types/radix-ng-primitives-toggle.d.ts +10 -3
  54. package/types/radix-ng-primitives-tooltip.d.ts +38 -14
@@ -4,9 +4,10 @@ import * as i1 from '@radix-ng/primitives/portal';
4
4
  import { RdxPortalContainer } from '@radix-ng/primitives/portal';
5
5
  import * as _radix_ng_primitives_core from '@radix-ng/primitives/core';
6
6
  import { RdxTransitionStatus, BooleanInput, RdxCancelableChangeEventDetails, RdxFloatingRootContext } from '@radix-ng/primitives/core';
7
+ import * as _radix_ng_primitives_floating_focus_manager from '@radix-ng/primitives/floating-focus-manager';
8
+ import { RdxInteractionType } from '@radix-ng/primitives/floating-focus-manager';
7
9
  import * as _radix_ng_primitives_dialog from '@radix-ng/primitives/dialog';
8
10
  import { RdxOutsidePressDomEvent } from '@radix-ng/primitives/dismissable-layer';
9
- import * as i2 from '@radix-ng/primitives/floating-focus-manager';
10
11
 
11
12
  /**
12
13
  * Structural directive that teleports the dialog content (backdrop + popup) into a container (default
@@ -106,6 +107,8 @@ interface RdxDialogRootContext {
106
107
  trigger: Signal<HTMLElement | undefined>;
107
108
  triggers: Signal<HTMLElement[]>;
108
109
  payload: Signal<unknown>;
110
+ openInteractionType: Signal<RdxInteractionType>;
111
+ closeInteractionType: Signal<RdxInteractionType>;
109
112
  /** Whether this dialog is nested in another; constant, fixed at construction. */
110
113
  nested: boolean;
111
114
  nestedDialogOpen: Signal<boolean>;
@@ -113,6 +116,7 @@ interface RdxDialogRootContext {
113
116
  setDescriptionId: (id: string | undefined) => void;
114
117
  registerTransitionElement: (element: HTMLElement) => () => void;
115
118
  registerTrigger: (id: string, trigger: HTMLElement, payload: () => unknown) => () => void;
119
+ setTriggerOpenInteractionType: (type: RdxInteractionType) => void;
116
120
  open: (trigger?: HTMLElement, payload?: unknown, triggerId?: string, reason?: RdxDialogOpenChangeReason, event?: Event) => void;
117
121
  close: (reason?: RdxDialogOpenChangeReason, event?: Event) => void;
118
122
  toggle: (triggerId: string, trigger: HTMLElement, payload?: unknown, event?: Event) => void;
@@ -178,7 +182,10 @@ declare class RdxDialogRoot {
178
182
  readonly triggers: _angular_core.WritableSignal<HTMLElement[]>;
179
183
  readonly payload: _angular_core.WritableSignal<unknown>;
180
184
  readonly nestedOpenCount: _angular_core.WritableSignal<number>;
185
+ readonly openInteractionType: _angular_core.WritableSignal<RdxInteractionType>;
186
+ readonly closeInteractionType: _angular_core.WritableSignal<RdxInteractionType>;
181
187
  private readonly preventUnmountOnClose;
188
+ private readonly pendingTriggerOpenInteractionType;
182
189
  readonly present: Signal<boolean>;
183
190
  /** Whether this dialog is rendered inside another dialog. Fixed at construction. */
184
191
  readonly nested: boolean;
@@ -199,12 +206,14 @@ declare class RdxDialogRoot {
199
206
  show(trigger?: HTMLElement | undefined, payload?: unknown, triggerId?: string, reason?: RdxDialogOpenChangeReason, event?: Event): void;
200
207
  close(reason?: RdxDialogOpenChangeReason, event?: Event): void;
201
208
  toggle(triggerId: string, trigger: HTMLElement, payload?: unknown, event?: Event): void;
209
+ setTriggerOpenInteractionType(type: RdxInteractionType): void;
202
210
  registerTrigger(id: string, trigger: HTMLElement, payload: () => unknown): () => void;
203
211
  /** Increments the nested-open counter and returns a release callback that decrements it. */
204
212
  openNestedChild(): () => void;
205
213
  private syncTriggerId;
206
214
  private createOpenChangeEvent;
207
215
  private emitOpenChangeComplete;
216
+ private consumeOpenInteractionType;
208
217
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxDialogRoot, never>;
209
218
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxDialogRoot, "[rdxDialogRoot]", ["rdxDialogRoot"], { "open": { "alias": "open"; "required": false; "isSignal": true; }; "defaultOpen": { "alias": "defaultOpen"; "required": false; "isSignal": true; }; "triggerId": { "alias": "triggerId"; "required": false; "isSignal": true; }; "defaultTriggerId": { "alias": "defaultTriggerId"; "required": false; "isSignal": true; }; "modal": { "alias": "modal"; "required": false; "isSignal": true; }; "disablePointerDismissal": { "alias": "disablePointerDismissal"; "required": false; "isSignal": true; }; "handle": { "alias": "handle"; "required": false; "isSignal": true; }; }, { "open": "openChange"; "triggerId": "triggerIdChange"; "onOpenChange": "onOpenChange"; "onOpenChangeComplete": "onOpenChangeComplete"; }, never, never, true, never>;
210
219
  }
@@ -235,8 +244,10 @@ declare class RdxDialogTrigger {
235
244
  protected readonly triggerId: _angular_core.Signal<string>;
236
245
  protected readonly rootContext: _angular_core.Signal<_radix_ng_primitives_dialog.RdxDialogRootContext | null>;
237
246
  protected readonly isOpen: _angular_core.Signal<boolean>;
247
+ protected readonly triggerInteraction: _radix_ng_primitives_floating_focus_manager.RdxTriggerInteraction;
238
248
  constructor();
239
249
  protected handleClick(event: MouseEvent): void;
250
+ protected handlePointerDown(event: PointerEvent): void;
240
251
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxDialogTrigger, never>;
241
252
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxDialogTrigger, "button[rdxDialogTrigger]", ["rdxDialogTrigger"], { "handle": { "alias": "handle"; "required": false; "isSignal": true; }; "payload": { "alias": "payload"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
242
253
  }
@@ -331,7 +342,7 @@ declare class RdxDialogPopup {
331
342
  */
332
343
  protected onKeyDown(event: KeyboardEvent): void;
333
344
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxDialogPopup, never>;
334
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxDialogPopup, "[rdxDialogPopup]", ["rdxDialogPopup"], {}, { "escapeKeyDown": "escapeKeyDown"; "pointerDownOutside": "pointerDownOutside"; "focusOutside": "focusOutside"; "interactOutside": "interactOutside"; "openAutoFocus": "openAutoFocus"; "closeAutoFocus": "closeAutoFocus"; }, never, never, true, [{ directive: typeof _radix_ng_primitives_core.RdxFloatingNodeRegistration; inputs: {}; outputs: {}; }, { directive: typeof i2.RdxFloatingFocusManager; inputs: {}; outputs: {}; }]>;
345
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxDialogPopup, "[rdxDialogPopup]", ["rdxDialogPopup"], {}, { "escapeKeyDown": "escapeKeyDown"; "pointerDownOutside": "pointerDownOutside"; "focusOutside": "focusOutside"; "interactOutside": "interactOutside"; "openAutoFocus": "openAutoFocus"; "closeAutoFocus": "closeAutoFocus"; }, never, never, true, [{ directive: typeof _radix_ng_primitives_core.RdxFloatingNodeRegistration; inputs: {}; outputs: {}; }, { directive: typeof _radix_ng_primitives_floating_focus_manager.RdxFloatingFocusManager; inputs: {}; outputs: {}; }]>;
335
346
  }
336
347
 
337
348
  /**
@@ -1,12 +1,18 @@
1
1
  import * as _angular_core from '@angular/core';
2
2
  import { Signal, WritableSignal } from '@angular/core';
3
3
  import * as _radix_ng_primitives_core from '@radix-ng/primitives/core';
4
- import { BooleanInput, NumberInput } from '@radix-ng/primitives/core';
4
+ import { BooleanInput, NumberInput, RdxCancelableChangeEventDetails } from '@radix-ng/primitives/core';
5
5
  import * as i1 from '@radix-ng/primitives/dismissable-layer';
6
6
  import * as _radix_ng_primitives_editable from '@radix-ng/primitives/editable';
7
7
 
8
8
  type EditableActivationMode = 'focus' | 'dblclick' | 'none';
9
9
  type EditableSubmitMode = 'blur' | 'enter' | 'none' | 'both';
10
+ type RdxEditableValueChangeReason = 'submit' | 'none';
11
+ type RdxEditableValueChangeEventDetails = RdxCancelableChangeEventDetails<RdxEditableValueChangeReason>;
12
+ interface RdxEditableValueChangeEvent {
13
+ value: string;
14
+ eventDetails: RdxEditableValueChangeEventDetails;
15
+ }
10
16
  type EditableRootContext = {
11
17
  disabled: Signal<boolean>;
12
18
  value: Signal<string | undefined>;
@@ -20,7 +26,7 @@ type EditableRootContext = {
20
26
  activationMode: Signal<EditableActivationMode>;
21
27
  edit: () => void;
22
28
  cancel: () => void;
23
- submit: () => void;
29
+ submit: (event?: Event) => void;
24
30
  maxLength: Signal<number | undefined>;
25
31
  required: Signal<boolean>;
26
32
  startWithEditMode: Signal<boolean>;
@@ -57,7 +63,7 @@ declare class RdxEditableRoot {
57
63
  readonly autoResize: _angular_core.InputSignalWithTransform<boolean, BooleanInput>;
58
64
  readonly required: _angular_core.InputSignalWithTransform<boolean, BooleanInput>;
59
65
  /** Emitted when the value is committed (on submit). */
60
- readonly onValueChange: _angular_core.OutputEmitterRef<string>;
66
+ readonly onValueChange: _angular_core.OutputEmitterRef<RdxEditableValueChangeEvent>;
61
67
  readonly isEmpty: Signal<boolean>;
62
68
  readonly $placeholder: Signal<{
63
69
  edit: string;
@@ -75,7 +81,7 @@ declare class RdxEditableRoot {
75
81
  constructor();
76
82
  canActivateOnFocus(): boolean;
77
83
  handleDismiss(): void;
78
- submit(): void;
84
+ submit(event?: Event): void;
79
85
  cancel(): void;
80
86
  edit(): void;
81
87
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxEditableRoot, never>;
@@ -144,4 +150,4 @@ declare class RdxEditableModule {
144
150
  }
145
151
 
146
152
  export { RdxEditableArea, RdxEditableCancelTrigger, RdxEditableEditTrigger, RdxEditableInput, RdxEditableModule, RdxEditablePreview, RdxEditableRoot, RdxEditableSubmitTrigger, injectEditableRootContext, provideEditableRootContext };
147
- export type { EditableActivationMode, EditableRootContext, EditableSubmitMode };
153
+ export type { EditableActivationMode, EditableRootContext, EditableSubmitMode, RdxEditableValueChangeEvent, RdxEditableValueChangeEventDetails, RdxEditableValueChangeReason };
@@ -1,6 +1,6 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { InjectionToken, Provider } from '@angular/core';
3
- import { BooleanInput } from '@radix-ng/primitives/core';
2
+ import { InjectionToken, Provider, Signal } from '@angular/core';
3
+ import { RdxFloatingTree, BooleanInput } from '@radix-ng/primitives/core';
4
4
  import * as i1 from '@radix-ng/primitives/focus-scope';
5
5
 
6
6
  /**
@@ -9,25 +9,25 @@ import * as i1 from '@radix-ng/primitives/focus-scope';
9
9
  * (Base UI keys `preferPreviousFocus = openInteractionType == null` off exactly this).
10
10
  */
11
11
  type RdxInteractionType = 'mouse' | 'touch' | 'pen' | 'keyboard' | '' | null;
12
- /** A focus target: an element, a getter, or `null`. */
13
- type RdxFocusTarget = HTMLElement | (() => HTMLElement | null) | null;
12
+ /** A focus target: an element, a getter, `null`, or `undefined` from a policy callback. */
13
+ type RdxFocusTarget = HTMLElement | (() => HTMLElement | null) | null | undefined;
14
14
  /** `initialFocus` policy (ADR 0017 §2) — a target, `false`, or an open-interaction callback. */
15
15
  type RdxInitialFocus = RdxFocusTarget | false | ((openInteractionType: RdxInteractionType) => RdxFocusTarget | false);
16
16
  /** `returnFocus` policy (ADR 0017 §2) — a target/boolean or a callback receiving the **close** interaction type. */
17
- type RdxReturnFocus = RdxFocusTarget | boolean | ((closeInteractionType: RdxInteractionType) => RdxFocusTarget | boolean);
17
+ type RdxReturnFocus = RdxFocusTarget | boolean | ((closeInteractionType: RdxInteractionType) => RdxFocusTarget | boolean | undefined);
18
18
  /** Normalizes a DOM event into Base UI-like interaction intent for focus policy decisions. */
19
19
  declare function getInteractionTypeFromEvent(event?: Event): RdxInteractionType;
20
20
  /** Resolves an {@link RdxFocusTarget} (element | getter | null) to a concrete element. */
21
- declare function resolveFocusTarget(target: RdxFocusTarget): HTMLElement | null;
21
+ declare function resolveFocusTarget(target: RdxFocusTarget): HTMLElement | null | undefined;
22
22
  /**
23
23
  * Resolves an {@link RdxInitialFocus} policy against how the popup opened.
24
24
  */
25
- declare function resolveInitialFocus(policy: RdxInitialFocus, openInteractionType: RdxInteractionType): HTMLElement | null | false;
25
+ declare function resolveInitialFocus(policy: RdxInitialFocus, openInteractionType: RdxInteractionType): HTMLElement | null | false | undefined;
26
26
  /**
27
27
  * Resolves an {@link RdxReturnFocus} policy against how the popup closed. `false` = do not return focus;
28
28
  * `true` = the default (return to the previously-focused element); an element = return there.
29
29
  */
30
- declare function resolveReturnFocus(policy: RdxReturnFocus, closeInteractionType: RdxInteractionType): HTMLElement | boolean | null;
30
+ declare function resolveReturnFocus(policy: RdxReturnFocus, closeInteractionType: RdxInteractionType): HTMLElement | boolean | null | undefined;
31
31
  /**
32
32
  * DI seam for a **composing primitive** (Dialog / Popover / Menu) to drive the manager's gates from its
33
33
  * own root context instead of template-bound inputs (which a primitive cannot set). Each field falls
@@ -40,9 +40,18 @@ interface RdxFloatingFocusManagerConfig {
40
40
  closeOnFocusOut?: () => boolean;
41
41
  initialFocus?: () => RdxInitialFocus;
42
42
  returnFocus?: () => RdxReturnFocus;
43
+ restoreFocus?: () => boolean | 'popup';
44
+ previousFocusableElement?: () => RdxFocusTarget;
45
+ nextFocusableElement?: () => RdxFocusTarget;
46
+ beforeContentFocusGuardRef?: () => RdxFocusGuardRef | null | undefined;
47
+ externalTree?: () => RdxFloatingTree | null | undefined;
48
+ getInsideElements?: () => Array<Element | null | undefined>;
43
49
  openInteractionType?: () => RdxInteractionType;
44
50
  closeInteractionType?: () => RdxInteractionType;
45
51
  }
52
+ type RdxFocusGuardRef = ((element: HTMLSpanElement | null) => void) | {
53
+ set: (element: HTMLSpanElement | null) => void;
54
+ };
46
55
  declare const RDX_FLOATING_FOCUS_MANAGER_CONFIG: InjectionToken<RdxFloatingFocusManagerConfig>;
47
56
  /** Provides a {@link RdxFloatingFocusManagerConfig} for an enclosing primitive's focus manager. */
48
57
  declare function provideFloatingFocusManagerConfig(factory: () => RdxFloatingFocusManagerConfig): Provider;
@@ -61,8 +70,7 @@ declare function provideFloatingFocusManagerConfig(factory: () => RdxFloatingFoc
61
70
  * - `loop` is forwarded to `RdxFocusScope`.
62
71
  * - `initialFocus` / `returnFocus` are **orchestrated** here (the §2 policy contract, incl. the
63
72
  * interaction-type callback forms): `initialFocus` via the scope's `mountAutoFocus` hook, `returnFocus`
64
- * via the scope's `returnFocus` config seam (resolved at the scope's queued post-unmount frame). The
65
- * portal-focus bridge remains a later-phase dependency.
73
+ * via the scope's `returnFocus` config seam (resolved at the scope's queued post-unmount frame).
66
74
  */
67
75
  declare class RdxFloatingFocusManager {
68
76
  /** Manager active-ness (ADR 0017 §2): the popup is mounted **and** not hover-opened. */
@@ -75,9 +83,25 @@ declare class RdxFloatingFocusManager {
75
83
  */
76
84
  readonly inert: _angular_core.InputSignalWithTransform<boolean | undefined, BooleanInput>;
77
85
  /** Where focus goes when the popup opens (ADR 0017 §2). */
78
- readonly initialFocus: _angular_core.InputSignal<RdxInitialFocus | undefined>;
86
+ readonly initialFocus: _angular_core.InputSignal<RdxInitialFocus>;
79
87
  /** Where focus returns when the popup closes (ADR 0017 §2). */
80
- readonly returnFocus: _angular_core.InputSignal<RdxReturnFocus | undefined>;
88
+ readonly returnFocus: _angular_core.InputSignal<RdxReturnFocus>;
89
+ /**
90
+ * Restores focus inside the floating tree when the currently focused inside element is removed and
91
+ * the browser drops focus onto `<body>` (Base UI `restoreFocus`). `true` restores to the last
92
+ * available tabbable candidate, `'popup'` restores to the popup container.
93
+ */
94
+ readonly restoreFocus: _angular_core.InputSignal<boolean | "popup" | undefined>;
95
+ /** Overrides where backward tabbing out of a non-modal portaled popup lands. */
96
+ readonly previousFocusableElement: _angular_core.InputSignal<RdxFocusTarget>;
97
+ /** Overrides where forward tabbing out of a non-modal portaled popup lands. */
98
+ readonly nextFocusableElement: _angular_core.InputSignal<RdxFocusTarget>;
99
+ /** Optional callback/signal that receives the leading content focus guard. */
100
+ readonly beforeContentFocusGuardRef: _angular_core.InputSignal<RdxFocusGuardRef | null | undefined>;
101
+ /** Explicit floating tree for detached sibling composition (Base UI `externalTree`). */
102
+ readonly externalTree: _angular_core.InputSignal<RdxFloatingTree | null | undefined>;
103
+ /** Additional elements treated as inside the floating subtree (Base UI `getInsideElements`). */
104
+ readonly getInsideElements: _angular_core.InputSignal<(() => Array<Element | null | undefined>) | undefined>;
81
105
  /**
82
106
  * Whether a **non-modal** popup closes when focus leaves to an unrelated node (Base UI
83
107
  * `closeOnFocusOut`, default `true`; Dialog sets it to `!disablePointerDismissal`). Modal popups
@@ -98,7 +122,13 @@ declare class RdxFloatingFocusManager {
98
122
  readonly effectiveInert: _angular_core.Signal<boolean>;
99
123
  readonly effectiveCloseOnFocusOut: _angular_core.Signal<boolean>;
100
124
  readonly effectiveInitialFocus: _angular_core.Signal<false | HTMLElement | ((openInteractionType: RdxInteractionType) => RdxFocusTarget | false) | null>;
101
- readonly effectiveReturnFocus: _angular_core.Signal<boolean | HTMLElement | ((closeInteractionType: RdxInteractionType) => RdxFocusTarget | boolean)>;
125
+ readonly effectiveReturnFocus: _angular_core.Signal<boolean | HTMLElement | ((closeInteractionType: RdxInteractionType) => RdxFocusTarget | boolean | undefined)>;
126
+ readonly effectiveRestoreFocus: _angular_core.Signal<boolean | "popup">;
127
+ readonly effectivePreviousFocusableElement: _angular_core.Signal<RdxFocusTarget>;
128
+ readonly effectiveNextFocusableElement: _angular_core.Signal<RdxFocusTarget>;
129
+ readonly effectiveBeforeContentFocusGuardRef: _angular_core.Signal<RdxFocusGuardRef | null | undefined>;
130
+ readonly effectiveExternalTree: _angular_core.Signal<RdxFloatingTree | null>;
131
+ readonly insideElements: _angular_core.Signal<Element[]>;
102
132
  readonly effectiveOpenInteractionType: _angular_core.Signal<RdxInteractionType>;
103
133
  readonly effectiveCloseInteractionType: _angular_core.Signal<RdxInteractionType>;
104
134
  /** The effective trap state the composed `RdxFocusScope` reads via its config token. */
@@ -155,6 +185,17 @@ declare class RdxFloatingFocusManager {
155
185
  * `FloatingFocusManager` `!modal` branch (`movedToUnrelatedNode`).
156
186
  */
157
187
  private wireCloseOnFocusOut;
188
+ /**
189
+ * Restore focus when an inside focused element disappears and the document focus falls back to
190
+ * `<body>`. This mirrors the practical Base UI `restoreFocus` path used by Select while keeping the
191
+ * broader portal-guard navigation separate.
192
+ */
193
+ private wireRestoreFocus;
194
+ /**
195
+ * Portal focus bridge (Base UI inside guards): when focus reaches the hidden guards around portaled
196
+ * content, redirect it either back inside the popup or to the configured neighboring tabbable node.
197
+ */
198
+ private wirePortalFocusBridge;
158
199
  /**
159
200
  * The marker keep-set is intentionally narrow: the popup/focus host only. Own sibling roots such as a
160
201
  * user backdrop are DOM-footprint bookkeeping, not marker keep-set members.
@@ -164,12 +205,68 @@ declare class RdxFloatingFocusManager {
164
205
  /** Whether `relatedTarget` is inside the popup, its trigger(s), or an ancestor / descendant popup. */
165
206
  private isRelatedTargetInside;
166
207
  private contextContains;
208
+ private currentFloatingNode;
209
+ private getTabbableContent;
210
+ private portalFocusContainer;
211
+ private defaultPreviousFocusable;
212
+ private defaultNextFocusable;
213
+ private setBeforeContentFocusGuardRef;
214
+ private isFromOutsideFocusGuard;
167
215
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxFloatingFocusManager, never>;
168
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxFloatingFocusManager, "[rdxFloatingFocusManager]", ["rdxFloatingFocusManager"], { "enabled": { "alias": "enabled"; "required": false; "isSignal": true; }; "modal": { "alias": "modal"; "required": false; "isSignal": true; }; "inert": { "alias": "inert"; "required": false; "isSignal": true; }; "initialFocus": { "alias": "initialFocus"; "required": false; "isSignal": true; }; "returnFocus": { "alias": "returnFocus"; "required": false; "isSignal": true; }; "closeOnFocusOut": { "alias": "closeOnFocusOut"; "required": false; "isSignal": true; }; }, { "focusOut": "focusOut"; }, never, never, true, [{ directive: typeof i1.RdxFocusScope; inputs: { "loop": "loop"; }; outputs: {}; }]>;
216
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxFloatingFocusManager, "[rdxFloatingFocusManager]", ["rdxFloatingFocusManager"], { "enabled": { "alias": "enabled"; "required": false; "isSignal": true; }; "modal": { "alias": "modal"; "required": false; "isSignal": true; }; "inert": { "alias": "inert"; "required": false; "isSignal": true; }; "initialFocus": { "alias": "initialFocus"; "required": false; "isSignal": true; }; "returnFocus": { "alias": "returnFocus"; "required": false; "isSignal": true; }; "restoreFocus": { "alias": "restoreFocus"; "required": false; "isSignal": true; }; "previousFocusableElement": { "alias": "previousFocusableElement"; "required": false; "isSignal": true; }; "nextFocusableElement": { "alias": "nextFocusableElement"; "required": false; "isSignal": true; }; "beforeContentFocusGuardRef": { "alias": "beforeContentFocusGuardRef"; "required": false; "isSignal": true; }; "externalTree": { "alias": "externalTree"; "required": false; "isSignal": true; }; "getInsideElements": { "alias": "getInsideElements"; "required": false; "isSignal": true; }; "closeOnFocusOut": { "alias": "closeOnFocusOut"; "required": false; "isSignal": true; }; }, { "focusOut": "focusOut"; }, never, never, true, [{ directive: typeof i1.RdxFocusScope; inputs: { "loop": "loop"; }; outputs: {}; }]>;
169
217
  }
170
218
 
171
219
  /** The neutral "outside the active floating layer" marker (Base UI `data-base-ui-inert`). */
172
220
  declare const RDX_FLOATING_MARKER = "data-rdx-floating-inert";
173
221
 
174
- export { RDX_FLOATING_FOCUS_MANAGER_CONFIG, RDX_FLOATING_MARKER, RdxFloatingFocusManager, getInteractionTypeFromEvent, provideFloatingFocusManagerConfig, resolveFocusTarget, resolveInitialFocus, resolveReturnFocus };
175
- export type { RdxFloatingFocusManagerConfig, RdxFocusTarget, RdxInitialFocus, RdxInteractionType, RdxReturnFocus };
222
+ interface RdxTriggerInteractionOptions {
223
+ trigger: () => HTMLElement;
224
+ open: () => boolean;
225
+ activeTrigger?: () => HTMLElement | null | undefined;
226
+ disabled?: () => boolean;
227
+ contentId?: () => string | null | undefined;
228
+ }
229
+ interface RdxTriggerInteraction {
230
+ readonly lastPointerType: Signal<string>;
231
+ readonly isActive: Signal<boolean>;
232
+ readonly isInactive: Signal<boolean>;
233
+ readonly dataState: Signal<'open' | 'closed'>;
234
+ readonly dataPopupOpen: Signal<'' | undefined>;
235
+ readonly ariaControls: Signal<string | undefined>;
236
+ readonly ariaExpanded: Signal<boolean>;
237
+ readonly disabled: Signal<boolean>;
238
+ recordPointerDown: (event: PointerEvent) => void;
239
+ clickInteractionType: (event: MouseEvent) => RdxInteractionType;
240
+ }
241
+ interface RdxTriggerFocusGuardOptions {
242
+ trigger: () => HTMLElement;
243
+ close: (event: FocusEvent) => void;
244
+ beforeContentFocusGuard?: () => HTMLElement | null | undefined;
245
+ contentId?: () => string | null | undefined;
246
+ enabled?: () => boolean;
247
+ popupElement?: () => HTMLElement | null | undefined;
248
+ }
249
+ interface RdxTriggerFocusGuardAnchorOptions {
250
+ trigger: () => HTMLElement;
251
+ contentId: () => string | null | undefined;
252
+ enabled?: () => boolean;
253
+ }
254
+ /**
255
+ * Shared trigger state for floating primitives. It intentionally stays small: each primitive still owns
256
+ * its open/close business rules, while this layer normalizes active-trigger state and the open method
257
+ * signal that must be captured before the popup/focus manager mounts.
258
+ */
259
+ declare function createRdxTriggerInteraction(options: RdxTriggerInteractionOptions): RdxTriggerInteraction;
260
+ /**
261
+ * Adds Base UI's trigger-side focus guards for portaled content. The content guards remain owned by
262
+ * `RdxFloatingFocusManager`; these guards bridge tab order from the trigger into the portal and close the
263
+ * popup when focus leaves past either trigger-side boundary.
264
+ */
265
+ declare function useTriggerFocusGuards(options: RdxTriggerFocusGuardOptions): void;
266
+ /**
267
+ * Backwards-compatible aria-owns-only bridge for modal popups that do not need trigger-side tab guards.
268
+ */
269
+ declare function useTriggerFocusGuardAnchor(options: RdxTriggerFocusGuardAnchorOptions): void;
270
+
271
+ export { RDX_FLOATING_FOCUS_MANAGER_CONFIG, RDX_FLOATING_MARKER, RdxFloatingFocusManager, createRdxTriggerInteraction, getInteractionTypeFromEvent, provideFloatingFocusManagerConfig, resolveFocusTarget, resolveInitialFocus, resolveReturnFocus, useTriggerFocusGuardAnchor, useTriggerFocusGuards };
272
+ export type { RdxFloatingFocusManagerConfig, RdxFocusGuardRef, RdxFocusTarget, RdxInitialFocus, RdxInteractionType, RdxReturnFocus, RdxTriggerFocusGuardAnchorOptions, RdxTriggerFocusGuardOptions, RdxTriggerInteraction, RdxTriggerInteractionOptions };
@@ -2,7 +2,7 @@ import * as _angular_core from '@angular/core';
2
2
  import { Signal, WritableSignal } from '@angular/core';
3
3
  import * as _radix_ng_primitives_core from '@radix-ng/primitives/core';
4
4
  import { RdxFloatingRootContext, BooleanInput, Direction, RdxCancelableChangeEventDetails, NumberInput } from '@radix-ng/primitives/core';
5
- import * as i3 from '@radix-ng/primitives/floating-focus-manager';
5
+ import * as _radix_ng_primitives_floating_focus_manager from '@radix-ng/primitives/floating-focus-manager';
6
6
  import { RdxInteractionType } from '@radix-ng/primitives/floating-focus-manager';
7
7
  import * as i1 from '@radix-ng/primitives/popper';
8
8
  import { RdxPopperContentWrapper } from '@radix-ng/primitives/popper';
@@ -71,6 +71,7 @@ interface RdxMenuRootContext {
71
71
  trigger: Signal<HTMLElement | undefined>;
72
72
  /** The popup element, once mounted. Used by submenu safe-polygon geometry. */
73
73
  popupElement: Signal<HTMLElement | undefined>;
74
+ beforeContentFocusGuard: Signal<HTMLElement | null>;
74
75
  transitionStatus: Signal<RdxMenuTransitionStatus>;
75
76
  close: (reason?: RdxMenuOpenChangeReason, event?: Event) => void;
76
77
  /** Close this menu and every ancestor — used by item selection (the whole menu dismisses). */
@@ -81,6 +82,7 @@ interface RdxMenuRootContext {
81
82
  showWithoutAutoFocus: (reason?: RdxMenuOpenChangeReason, event?: Event) => void;
82
83
  registerTrigger: (el: HTMLElement) => () => void;
83
84
  registerPopup: (el: HTMLElement) => () => void;
85
+ setBeforeContentFocusGuard: (element: HTMLElement | null) => void;
84
86
  registerTransitionElement: (element: HTMLElement) => () => void;
85
87
  registerPopupArrowNavigationHandler: (handler: (offset: 1 | -1) => boolean) => () => void;
86
88
  registerTriggerInteractionHandler: (handler: RdxMenuTriggerInteractionHandler) => () => void;
@@ -174,6 +176,7 @@ declare class RdxMenuRoot {
174
176
  readonly onOpenChangeComplete: _angular_core.OutputEmitterRef<boolean>;
175
177
  readonly trigger: _angular_core.WritableSignal<HTMLElement | undefined>;
176
178
  readonly popupElement: _angular_core.WritableSignal<HTMLElement | undefined>;
179
+ readonly beforeContentFocusGuard: _angular_core.WritableSignal<HTMLElement | null>;
177
180
  readonly transitionStatus: Signal<_radix_ng_primitives_core.RdxTransitionStatus>;
178
181
  /** Whether the popup grabs focus when it opens. Set false for menubar hover-switching. */
179
182
  readonly autoFocus: _angular_core.WritableSignal<RdxMenuAutoFocus>;
@@ -214,6 +217,7 @@ declare class RdxMenuRoot {
214
217
  closeEntireMenu(reason?: RdxMenuOpenChangeReason, event?: Event): void;
215
218
  registerTrigger(el: HTMLElement): () => void;
216
219
  registerPopup(el: HTMLElement): () => void;
220
+ setBeforeContentFocusGuard(element: HTMLElement | null): void;
217
221
  registerTransitionElement(element: HTMLElement): () => void;
218
222
  registerPopupArrowNavigationHandler(handler: (offset: 1 | -1) => boolean): () => void;
219
223
  handlePopupArrowNavigation(offset: 1 | -1): boolean;
@@ -253,8 +257,10 @@ declare class RdxMenuTrigger {
253
257
  readonly closeDelay: _angular_core.InputSignalWithTransform<number | undefined, NumberInput>;
254
258
  protected readonly nativeButtonState: _angular_core.Signal<boolean>;
255
259
  protected readonly isDisabled: _angular_core.Signal<boolean>;
260
+ protected readonly triggerInteraction: _radix_ng_primitives_floating_focus_manager.RdxTriggerInteraction;
256
261
  constructor();
257
262
  protected handleMouseDown(event: MouseEvent): void;
263
+ protected handlePointerDown(event: PointerEvent): void;
258
264
  protected handleClick(event: MouseEvent): void;
259
265
  protected handleArrowDown(event: Event): void;
260
266
  protected handleArrowUp(event: Event): void;
@@ -416,7 +422,7 @@ declare class RdxMenuPopup {
416
422
  private scheduleSubmenuKeyboardFocus;
417
423
  private applySubmenuKeyboardFocus;
418
424
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxMenuPopup, never>;
419
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxMenuPopup, "[rdxMenuPopup]", ["rdxMenuPopup"], {}, { "escapeKeyDown": "escapeKeyDown"; "pointerDownOutside": "pointerDownOutside"; "focusOutside": "focusOutside"; "interactOutside": "interactOutside"; "openAutoFocus": "openAutoFocus"; "closeAutoFocus": "closeAutoFocus"; }, never, never, true, [{ directive: typeof i1.RdxPopperContent; inputs: {}; outputs: {}; }, { directive: typeof _radix_ng_primitives_core.RdxFloatingNodeRegistration; inputs: {}; outputs: {}; }, { directive: typeof i3.RdxFloatingFocusManager; inputs: {}; outputs: {}; }]>;
425
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxMenuPopup, "[rdxMenuPopup]", ["rdxMenuPopup"], {}, { "escapeKeyDown": "escapeKeyDown"; "pointerDownOutside": "pointerDownOutside"; "focusOutside": "focusOutside"; "interactOutside": "interactOutside"; "openAutoFocus": "openAutoFocus"; "closeAutoFocus": "closeAutoFocus"; }, never, never, true, [{ directive: typeof i1.RdxPopperContent; inputs: {}; outputs: {}; }, { directive: typeof _radix_ng_primitives_core.RdxFloatingNodeRegistration; inputs: {}; outputs: {}; }, { directive: typeof _radix_ng_primitives_floating_focus_manager.RdxFloatingFocusManager; inputs: {}; outputs: {}; }]>;
420
426
  }
421
427
 
422
428
  /**
@@ -1,7 +1,7 @@
1
1
  import * as _angular_core from '@angular/core';
2
2
  import { Signal } from '@angular/core';
3
3
  import * as _radix_ng_primitives_core from '@radix-ng/primitives/core';
4
- import { RdxFormValueControl, RdxControlValueAccessor, NumberInput, BooleanInput } from '@radix-ng/primitives/core';
4
+ import { RdxFormValueControl, RdxControlValueAccessor, NumberInput, BooleanInput, RdxCancelableChangeEventDetails } from '@radix-ng/primitives/core';
5
5
  import * as _radix_ng_primitives_number_field from '@radix-ng/primitives/number-field';
6
6
  import { NumberFormatter, NumberParser } from '@internationalized/number';
7
7
  import * as i1 from '@radix-ng/primitives/portal';
@@ -35,6 +35,11 @@ declare const REASONS: {
35
35
  readonly none: "none";
36
36
  };
37
37
 
38
+ type RdxNumberFieldValueChangeEventDetails = RdxCancelableChangeEventDetails<NumberFieldChangeReason>;
39
+ interface RdxNumberFieldValueChangeEvent {
40
+ value: number | null;
41
+ eventDetails: RdxNumberFieldValueChangeEventDetails;
42
+ }
38
43
  /**
39
44
  * Groups all parts of the number field and manages its state, parsing/formatting
40
45
  * and value-change logic. A single directive drives the whole family — parts read
@@ -110,7 +115,7 @@ declare class RdxNumberFieldRoot implements RdxFormValueControl<number | null> {
110
115
  /** The controlled value of the field. Use with `(onValueChange)` or two-way `[(value)]`. */
111
116
  readonly value: _angular_core.ModelSignal<number | null>;
112
117
  /** Emitted when the value changes (during interaction or programmatically). */
113
- readonly onValueChange: _angular_core.OutputEmitterRef<number | null>;
118
+ readonly onValueChange: _angular_core.OutputEmitterRef<RdxNumberFieldValueChangeEvent>;
114
119
  /**
115
120
  * Emitted when the value is committed: on blur after typing, or when a pointer is released
116
121
  * after scrubbing or pressing a button. Fires together with `onValueChange` for keyboard input.
@@ -461,4 +466,4 @@ declare class RdxNumberFieldModule {
461
466
  }
462
467
 
463
468
  export { CHANGE_VALUE_TICK_DELAY, DEFAULT_STEP, REASONS, RdxNumberFieldButton, RdxNumberFieldDecrement, RdxNumberFieldGroup, RdxNumberFieldHiddenInput, RdxNumberFieldIncrement, RdxNumberFieldInput, RdxNumberFieldModule, RdxNumberFieldRoot, RdxNumberFieldScrubArea, RdxNumberFieldScrubAreaCursor, SCROLLING_POINTER_MOVE_DISTANCE, START_AUTO_CHANGE_DELAY, createPressAndHold, hasNumberFormatRoundingOptions, injectNumberFieldRootContext, injectNumberFieldScrubAreaContext, numberOrUndefined, provideNumberFieldRootContext, provideNumberFieldScrubAreaContext, removeFloatingPointErrors, toValidatedNumber, useNumberFormatter, useNumberParser };
464
- export type { Direction, InputMode, NumberFieldChangeReason, PressAndHold, PressAndHoldOptions, RdxNumberFieldScrubAreaContext, ValidateOptions };
469
+ export type { Direction, InputMode, NumberFieldChangeReason, PressAndHold, PressAndHoldOptions, RdxNumberFieldScrubAreaContext, RdxNumberFieldValueChangeEvent, RdxNumberFieldValueChangeEventDetails, ValidateOptions };
@@ -3,11 +3,12 @@ import { Signal, ElementRef } from '@angular/core';
3
3
  import * as i1 from '@radix-ng/primitives/portal';
4
4
  import * as _radix_ng_primitives_core from '@radix-ng/primitives/core';
5
5
  import { RdxTransitionStatus, RdxFloatingRootContext, BooleanInput, RdxCancelableChangeEventDetails, NumberInput } from '@radix-ng/primitives/core';
6
+ import * as _radix_ng_primitives_floating_focus_manager from '@radix-ng/primitives/floating-focus-manager';
7
+ import { RdxInteractionType } from '@radix-ng/primitives/floating-focus-manager';
6
8
  import * as i1$1 from '@radix-ng/primitives/popper';
7
9
  import { RdxPopperContentWrapper } from '@radix-ng/primitives/popper';
8
10
  import * as _radix_ng_primitives_popover from '@radix-ng/primitives/popover';
9
11
  import { RdxOutsidePressDomEvent } from '@radix-ng/primitives/dismissable-layer';
10
- import * as i3 from '@radix-ng/primitives/floating-focus-manager';
11
12
 
12
13
  /**
13
14
  * Structural directive that teleports the popover content into a container (default `document.body`)
@@ -73,6 +74,8 @@ interface RdxPopoverRootContext {
73
74
  isPointerDownOnTrigger: Signal<boolean>;
74
75
  /** Whether the current open was initiated by touch (ADR 0016 §3 — gates the anchored scroll lock). */
75
76
  openedByTouch: Signal<boolean>;
77
+ openInteractionType: Signal<RdxInteractionType>;
78
+ closeInteractionType: Signal<RdxInteractionType>;
76
79
  close: (reason?: RdxPopoverOpenChangeReason, event?: Event) => void;
77
80
  cancelHoverClose: () => void;
78
81
  cancelHoverOpen: () => void;
@@ -85,11 +88,14 @@ interface RdxPopoverRootContext {
85
88
  setTitleId: (id: string | undefined) => void;
86
89
  setPointerDownOnTrigger: (pointerDown: boolean) => void;
87
90
  setOpenedByTouch: (value: boolean) => void;
91
+ setTriggerOpenInteractionType: (type: RdxInteractionType) => void;
88
92
  setHoverDelays: (delay: number, closeDelay: number) => void;
89
93
  registerPopupClose: () => () => void;
90
94
  registerTransitionElement: (element: HTMLElement) => () => void;
91
95
  transitionStatus: Signal<RdxPopoverTransitionStatus>;
96
+ beforeContentFocusGuard: Signal<HTMLElement | null>;
92
97
  registerViewport: (onTriggerChange: (previous: HTMLElement, next: HTMLElement) => void) => () => void;
98
+ setBeforeContentFocusGuard: (element: HTMLElement | null) => void;
93
99
  toggle: (triggerId: string, trigger: HTMLElement, payload?: unknown, event?: Event) => void;
94
100
  }
95
101
  declare const injectRdxPopoverRootContext: _radix_ng_primitives_core.InjectContext<RdxPopoverRootContext>;
@@ -140,6 +146,7 @@ declare class RdxPopoverRoot {
140
146
  */
141
147
  readonly handle: _angular_core.InputSignal<RdxPopoverHandle<any> | undefined>;
142
148
  readonly contentId: string;
149
+ readonly beforeContentFocusGuard: _angular_core.WritableSignal<HTMLElement | null>;
143
150
  readonly descriptionId: _angular_core.WritableSignal<string | undefined>;
144
151
  readonly titleId: _angular_core.WritableSignal<string | undefined>;
145
152
  readonly trigger: _angular_core.WritableSignal<HTMLElement | undefined>;
@@ -148,8 +155,11 @@ declare class RdxPopoverRoot {
148
155
  readonly isPointerDownOnTrigger: _angular_core.WritableSignal<boolean>;
149
156
  /** Whether the current open was initiated by touch (ADR 0016 §3 — gates the anchored scroll lock). */
150
157
  readonly openedByTouch: _angular_core.WritableSignal<boolean>;
158
+ readonly openInteractionType: _angular_core.WritableSignal<RdxInteractionType>;
159
+ readonly closeInteractionType: _angular_core.WritableSignal<RdxInteractionType>;
151
160
  readonly popupCloseCount: _angular_core.WritableSignal<number>;
152
161
  private readonly preventUnmountOnClose;
162
+ private readonly pendingTriggerOpenInteractionType;
153
163
  readonly onOpenChange: _angular_core.OutputEmitterRef<RdxPopoverOpenChange>;
154
164
  readonly onOpenChangeComplete: _angular_core.OutputEmitterRef<boolean>;
155
165
  private readonly registeredTriggers;
@@ -165,8 +175,10 @@ declare class RdxPopoverRoot {
165
175
  cancelHoverClose(): void;
166
176
  cancelHoverOpen(): void;
167
177
  setHoverDelays(delay: number, closeDelay: number): void;
178
+ setTriggerOpenInteractionType(type: RdxInteractionType): void;
168
179
  registerTrigger(id: string, trigger: HTMLElement, payload: () => unknown): () => void;
169
180
  registerViewport(onTriggerChange: (previous: HTMLElement, next: HTMLElement) => void): () => boolean;
181
+ setBeforeContentFocusGuard(element: HTMLElement | null): void;
170
182
  registerTransitionElement(element: HTMLElement): () => void;
171
183
  private syncTriggerId;
172
184
  private createOpenChangeEvent;
@@ -174,6 +186,7 @@ declare class RdxPopoverRoot {
174
186
  private clearOpenTimer;
175
187
  private clearCloseTimer;
176
188
  private scheduleInstantReset;
189
+ private consumeOpenInteractionType;
177
190
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxPopoverRoot, never>;
178
191
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxPopoverRoot, "[rdxPopoverRoot]", ["rdxPopoverRoot"], { "open": { "alias": "open"; "required": false; "isSignal": true; }; "defaultOpen": { "alias": "defaultOpen"; "required": false; "isSignal": true; }; "triggerId": { "alias": "triggerId"; "required": false; "isSignal": true; }; "defaultTriggerId": { "alias": "defaultTriggerId"; "required": false; "isSignal": true; }; "modal": { "alias": "modal"; "required": false; "isSignal": true; }; "handle": { "alias": "handle"; "required": false; "isSignal": true; }; }, { "open": "openChange"; "triggerId": "triggerIdChange"; "onOpenChange": "onOpenChange"; "onOpenChangeComplete": "onOpenChangeComplete"; }, never, never, true, [{ directive: typeof i1$1.RdxPopper; inputs: {}; outputs: {}; }]>;
179
192
  }
@@ -184,8 +197,6 @@ declare class RdxPopoverRoot {
184
197
  declare class RdxPopoverTrigger {
185
198
  private readonly parentRootContext;
186
199
  readonly elementRef: ElementRef<HTMLElement>;
187
- /** Pointer type of the most recent `pointerdown`, used to detect a touch open (ADR 0016 §3). */
188
- private lastPointerType;
189
200
  /**
190
201
  * Associates this trigger with a detached popover root.
191
202
  */
@@ -217,6 +228,7 @@ declare class RdxPopoverTrigger {
217
228
  protected readonly triggerId: _angular_core.Signal<string>;
218
229
  protected readonly rootContext: _angular_core.Signal<_radix_ng_primitives_popover.RdxPopoverRootContext | null>;
219
230
  protected readonly isOpen: _angular_core.Signal<boolean>;
231
+ protected readonly triggerInteraction: _radix_ng_primitives_floating_focus_manager.RdxTriggerInteraction;
220
232
  protected readonly isPressed: _angular_core.Signal<boolean>;
221
233
  private readonly generatedId;
222
234
  constructor();
@@ -272,8 +284,8 @@ declare class RdxPopoverPositioner extends RdxPopperContentWrapper {
272
284
  * - No `disablePointerDismissal` — outside-press + focus-out always close.
273
285
  *
274
286
  * Note: a positioned popover does **not** auto-focus into the popup on open (pre-existing — the legacy
275
- * behaved the same; verified). The trap holds focus once it is inside. Auto-focus-on-open + redirecting a
276
- * Tab from the trigger into the popup needs the deferred portal-focus bridge / guards (ADR 0017 §6a).
287
+ * behaved the same; verified). The trap holds focus once it is inside; portal tab-order handoff is owned
288
+ * by `RdxFloatingFocusManager` and anchored to the active trigger below.
277
289
  */
278
290
  declare class RdxPopoverPopup {
279
291
  protected readonly rootContext: _radix_ng_primitives_popover.RdxPopoverRootContext;
@@ -299,7 +311,7 @@ declare class RdxPopoverPopup {
299
311
  readonly closeAutoFocus: _angular_core.OutputRef<Event>;
300
312
  constructor();
301
313
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxPopoverPopup, never>;
302
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxPopoverPopup, "[rdxPopoverPopup]", never, {}, { "escapeKeyDown": "escapeKeyDown"; "pointerDownOutside": "pointerDownOutside"; "focusOutside": "focusOutside"; "interactOutside": "interactOutside"; "openAutoFocus": "openAutoFocus"; "closeAutoFocus": "closeAutoFocus"; }, never, never, true, [{ directive: typeof i1$1.RdxPopperContent; inputs: {}; outputs: {}; }, { directive: typeof _radix_ng_primitives_core.RdxFloatingNodeRegistration; inputs: {}; outputs: {}; }, { directive: typeof i3.RdxFloatingFocusManager; inputs: {}; outputs: {}; }]>;
314
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxPopoverPopup, "[rdxPopoverPopup]", never, {}, { "escapeKeyDown": "escapeKeyDown"; "pointerDownOutside": "pointerDownOutside"; "focusOutside": "focusOutside"; "interactOutside": "interactOutside"; "openAutoFocus": "openAutoFocus"; "closeAutoFocus": "closeAutoFocus"; }, never, never, true, [{ directive: typeof i1$1.RdxPopperContent; inputs: {}; outputs: {}; }, { directive: typeof _radix_ng_primitives_core.RdxFloatingNodeRegistration; inputs: {}; outputs: {}; }, { directive: typeof _radix_ng_primitives_floating_focus_manager.RdxFloatingFocusManager; inputs: {}; outputs: {}; }]>;
303
315
  }
304
316
 
305
317
  /**
@@ -1,7 +1,7 @@
1
1
  import * as _angular_core from '@angular/core';
2
2
  import { ModelSignal, InputSignal, InputSignalWithTransform, Signal, InjectionToken } from '@angular/core';
3
3
  import { ControlValueAccessor } from '@angular/forms';
4
- import { BooleanInput, RdxFormValueControl } from '@radix-ng/primitives/core';
4
+ import { BooleanInput, RdxFormValueControl, RdxCancelableChangeEventDetails } from '@radix-ng/primitives/core';
5
5
  import * as i1 from '@radix-ng/primitives/roving-focus';
6
6
  import { Orientation } from '@radix-ng/primitives/roving-focus';
7
7
  import * as i1$1 from '@radix-ng/primitives/visually-hidden';
@@ -18,12 +18,18 @@ interface RadioGroupProps {
18
18
  disabledState: Signal<boolean>;
19
19
  }
20
20
  interface RadioGroupDirective extends RadioGroupProps {
21
- select(value: string | null): void;
21
+ select(value: string | null, event?: Event, reason?: string): void;
22
22
  onTouched(): void;
23
23
  setArrowNavigation(value: boolean): void;
24
24
  isArrowNavigation(): boolean;
25
25
  }
26
26
 
27
+ type RdxRadioValueChangeReason = 'trigger-press' | 'keyboard' | 'focus' | 'none';
28
+ type RdxRadioValueChangeEventDetails = RdxCancelableChangeEventDetails<RdxRadioValueChangeReason>;
29
+ interface RdxRadioValueChangeEvent {
30
+ value: string;
31
+ eventDetails: RdxRadioValueChangeEventDetails;
32
+ }
27
33
  declare class RdxRadioGroupDirective implements RadioGroupProps, RadioGroupDirective, ControlValueAccessor, RdxFormValueControl<string | null> {
28
34
  readonly value: _angular_core.ModelSignal<string | null>;
29
35
  readonly defaultValue: _angular_core.InputSignal<string | undefined>;
@@ -36,7 +42,7 @@ declare class RdxRadioGroupDirective implements RadioGroupProps, RadioGroupDirec
36
42
  /**
37
43
  * Event handler called when the value changes.
38
44
  */
39
- readonly onValueChange: _angular_core.OutputEmitterRef<string>;
45
+ readonly onValueChange: _angular_core.OutputEmitterRef<RdxRadioValueChangeEvent>;
40
46
  private readonly disable;
41
47
  readonly disabledState: _angular_core.Signal<boolean>;
42
48
  private readonly arrowNavigation;
@@ -55,7 +61,7 @@ declare class RdxRadioGroupDirective implements RadioGroupProps, RadioGroupDirec
55
61
  * @param value The value of the radio item to select.
56
62
  * @ignore
57
63
  */
58
- select(value: string | null): void;
64
+ select(value: string | null, event?: Event, reason?: RdxRadioValueChangeReason): void;
59
65
  /**
60
66
  * Update the value of the radio group.
61
67
  * @param value The new value of the radio group.
@@ -107,13 +113,13 @@ declare class RdxRadioItemDirective {
107
113
  private readonly ARROW_KEYS;
108
114
  constructor();
109
115
  /** @ignore */
110
- onClick(): void;
116
+ onClick(event?: Event): void;
111
117
  /** @ignore */
112
118
  onKeyDown(event: Event): void;
113
119
  /** @ignore */
114
120
  onKeyUp(): void;
115
121
  /** @ignore */
116
- onFocus(): void;
122
+ onFocus(event?: FocusEvent): void;
117
123
  private isAllowedArrowKey;
118
124
  private createHiddenInput;
119
125
  private syncHiddenInput;
@@ -146,3 +152,4 @@ declare class RdxRadioItemInputDirective {
146
152
  }
147
153
 
148
154
  export { RdxRadioGroupDirective, RdxRadioIndicatorDirective, RdxRadioItemDirective, RdxRadioItemInputDirective, RdxRadioItemToken, injectRadioItem };
155
+ export type { RdxRadioValueChangeEvent, RdxRadioValueChangeEventDetails, RdxRadioValueChangeReason };