@radix-ng/primitives 1.0.0-beta.3 → 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 (118) hide show
  1. package/README.md +1 -1
  2. package/fesm2022/radix-ng-primitives-accordion.mjs +5 -3
  3. package/fesm2022/radix-ng-primitives-accordion.mjs.map +1 -1
  4. package/fesm2022/radix-ng-primitives-alert-dialog.mjs +3 -2
  5. package/fesm2022/radix-ng-primitives-alert-dialog.mjs.map +1 -1
  6. package/fesm2022/radix-ng-primitives-autocomplete.mjs +617 -659
  7. package/fesm2022/radix-ng-primitives-autocomplete.mjs.map +1 -1
  8. package/fesm2022/radix-ng-primitives-calendar.mjs +5 -3
  9. package/fesm2022/radix-ng-primitives-calendar.mjs.map +1 -1
  10. package/fesm2022/radix-ng-primitives-checkbox.mjs +33 -18
  11. package/fesm2022/radix-ng-primitives-checkbox.mjs.map +1 -1
  12. package/fesm2022/radix-ng-primitives-combobox.mjs +1305 -572
  13. package/fesm2022/radix-ng-primitives-combobox.mjs.map +1 -1
  14. package/fesm2022/radix-ng-primitives-config.mjs +13 -4
  15. package/fesm2022/radix-ng-primitives-config.mjs.map +1 -1
  16. package/fesm2022/radix-ng-primitives-context-menu.mjs +51 -10
  17. package/fesm2022/radix-ng-primitives-context-menu.mjs.map +1 -1
  18. package/fesm2022/radix-ng-primitives-core.mjs +1352 -64
  19. package/fesm2022/radix-ng-primitives-core.mjs.map +1 -1
  20. package/fesm2022/radix-ng-primitives-date-field.mjs +5 -3
  21. package/fesm2022/radix-ng-primitives-date-field.mjs.map +1 -1
  22. package/fesm2022/radix-ng-primitives-dialog.mjs +290 -120
  23. package/fesm2022/radix-ng-primitives-dialog.mjs.map +1 -1
  24. package/fesm2022/radix-ng-primitives-direction-provider.mjs +70 -0
  25. package/fesm2022/radix-ng-primitives-direction-provider.mjs.map +1 -0
  26. package/fesm2022/radix-ng-primitives-dismissable-layer.mjs +519 -184
  27. package/fesm2022/radix-ng-primitives-dismissable-layer.mjs.map +1 -1
  28. package/fesm2022/radix-ng-primitives-drawer.mjs +3 -3
  29. package/fesm2022/radix-ng-primitives-drawer.mjs.map +1 -1
  30. package/fesm2022/radix-ng-primitives-editable.mjs +12 -7
  31. package/fesm2022/radix-ng-primitives-editable.mjs.map +1 -1
  32. package/fesm2022/radix-ng-primitives-field.mjs +3 -2
  33. package/fesm2022/radix-ng-primitives-field.mjs.map +1 -1
  34. package/fesm2022/radix-ng-primitives-floating-focus-manager.mjs +803 -0
  35. package/fesm2022/radix-ng-primitives-floating-focus-manager.mjs.map +1 -0
  36. package/fesm2022/radix-ng-primitives-focus-scope.mjs +305 -70
  37. package/fesm2022/radix-ng-primitives-focus-scope.mjs.map +1 -1
  38. package/fesm2022/radix-ng-primitives-menu.mjs +893 -289
  39. package/fesm2022/radix-ng-primitives-menu.mjs.map +1 -1
  40. package/fesm2022/radix-ng-primitives-menubar.mjs +32 -4
  41. package/fesm2022/radix-ng-primitives-menubar.mjs.map +1 -1
  42. package/fesm2022/radix-ng-primitives-navigation-menu.mjs +144 -159
  43. package/fesm2022/radix-ng-primitives-navigation-menu.mjs.map +1 -1
  44. package/fesm2022/radix-ng-primitives-number-field.mjs +7 -2
  45. package/fesm2022/radix-ng-primitives-number-field.mjs.map +1 -1
  46. package/fesm2022/radix-ng-primitives-popover.mjs +284 -212
  47. package/fesm2022/radix-ng-primitives-popover.mjs.map +1 -1
  48. package/fesm2022/radix-ng-primitives-popper.mjs +94 -51
  49. package/fesm2022/radix-ng-primitives-popper.mjs.map +1 -1
  50. package/fesm2022/radix-ng-primitives-presence.mjs +1 -1
  51. package/fesm2022/radix-ng-primitives-presence.mjs.map +1 -1
  52. package/fesm2022/radix-ng-primitives-preview-card.mjs +141 -173
  53. package/fesm2022/radix-ng-primitives-preview-card.mjs.map +1 -1
  54. package/fesm2022/radix-ng-primitives-radio.mjs +19 -14
  55. package/fesm2022/radix-ng-primitives-radio.mjs.map +1 -1
  56. package/fesm2022/radix-ng-primitives-roving-focus.mjs +4 -2
  57. package/fesm2022/radix-ng-primitives-roving-focus.mjs.map +1 -1
  58. package/fesm2022/radix-ng-primitives-scroll-area.mjs +5 -4
  59. package/fesm2022/radix-ng-primitives-scroll-area.mjs.map +1 -1
  60. package/fesm2022/radix-ng-primitives-select.mjs +241 -164
  61. package/fesm2022/radix-ng-primitives-select.mjs.map +1 -1
  62. package/fesm2022/radix-ng-primitives-slider.mjs +262 -29
  63. package/fesm2022/radix-ng-primitives-slider.mjs.map +1 -1
  64. package/fesm2022/radix-ng-primitives-stepper.mjs +16 -10
  65. package/fesm2022/radix-ng-primitives-stepper.mjs.map +1 -1
  66. package/fesm2022/radix-ng-primitives-switch.mjs +10 -5
  67. package/fesm2022/radix-ng-primitives-switch.mjs.map +1 -1
  68. package/fesm2022/radix-ng-primitives-tabs.mjs +15 -10
  69. package/fesm2022/radix-ng-primitives-tabs.mjs.map +1 -1
  70. package/fesm2022/radix-ng-primitives-time-field.mjs +5 -3
  71. package/fesm2022/radix-ng-primitives-time-field.mjs.map +1 -1
  72. package/fesm2022/radix-ng-primitives-toast.mjs +15 -36
  73. package/fesm2022/radix-ng-primitives-toast.mjs.map +1 -1
  74. package/fesm2022/radix-ng-primitives-toggle-group.mjs +14 -7
  75. package/fesm2022/radix-ng-primitives-toggle-group.mjs.map +1 -1
  76. package/fesm2022/radix-ng-primitives-toggle.mjs +12 -6
  77. package/fesm2022/radix-ng-primitives-toggle.mjs.map +1 -1
  78. package/fesm2022/radix-ng-primitives-toolbar.mjs +5 -3
  79. package/fesm2022/radix-ng-primitives-toolbar.mjs.map +1 -1
  80. package/fesm2022/radix-ng-primitives-tooltip.mjs +251 -143
  81. package/fesm2022/radix-ng-primitives-tooltip.mjs.map +1 -1
  82. package/package.json +10 -1
  83. package/types/radix-ng-primitives-accordion.d.ts +4 -3
  84. package/types/radix-ng-primitives-autocomplete.d.ts +217 -152
  85. package/types/radix-ng-primitives-calendar.d.ts +5 -3
  86. package/types/radix-ng-primitives-checkbox.d.ts +27 -15
  87. package/types/radix-ng-primitives-combobox.d.ts +672 -283
  88. package/types/radix-ng-primitives-config.d.ts +1 -1
  89. package/types/radix-ng-primitives-context-menu.d.ts +15 -5
  90. package/types/radix-ng-primitives-core.d.ts +764 -14
  91. package/types/radix-ng-primitives-date-field.d.ts +3 -2
  92. package/types/radix-ng-primitives-dialog.d.ts +88 -32
  93. package/types/radix-ng-primitives-direction-provider.d.ts +41 -0
  94. package/types/radix-ng-primitives-dismissable-layer.d.ts +147 -99
  95. package/types/radix-ng-primitives-editable.d.ts +11 -5
  96. package/types/radix-ng-primitives-field.d.ts +1 -0
  97. package/types/radix-ng-primitives-floating-focus-manager.d.ts +272 -0
  98. package/types/radix-ng-primitives-focus-scope.d.ts +132 -1
  99. package/types/radix-ng-primitives-menu.d.ts +192 -103
  100. package/types/radix-ng-primitives-navigation-menu.d.ts +37 -75
  101. package/types/radix-ng-primitives-number-field.d.ts +8 -3
  102. package/types/radix-ng-primitives-popover.d.ts +71 -92
  103. package/types/radix-ng-primitives-popper.d.ts +39 -9
  104. package/types/radix-ng-primitives-preview-card.d.ts +39 -72
  105. package/types/radix-ng-primitives-radio.d.ts +13 -6
  106. package/types/radix-ng-primitives-roving-focus.d.ts +7 -6
  107. package/types/radix-ng-primitives-scroll-area.d.ts +2 -2
  108. package/types/radix-ng-primitives-select.d.ts +142 -109
  109. package/types/radix-ng-primitives-slider.d.ts +64 -12
  110. package/types/radix-ng-primitives-stepper.d.ts +15 -7
  111. package/types/radix-ng-primitives-switch.d.ts +10 -4
  112. package/types/radix-ng-primitives-tabs.d.ts +12 -6
  113. package/types/radix-ng-primitives-time-field.d.ts +3 -2
  114. package/types/radix-ng-primitives-toast.d.ts +7 -7
  115. package/types/radix-ng-primitives-toggle-group.d.ts +15 -8
  116. package/types/radix-ng-primitives-toggle.d.ts +10 -3
  117. package/types/radix-ng-primitives-toolbar.d.ts +3 -2
  118. package/types/radix-ng-primitives-tooltip.d.ts +61 -80
@@ -26,7 +26,8 @@ declare class RdxDateFieldRootDirective {
26
26
  * The locale to use for formatting dates.
27
27
  */
28
28
  readonly locale: _angular_core.InputSignal<string>;
29
- readonly dir: _angular_core.InputSignal<Direction>;
29
+ readonly dirInput: _angular_core.InputSignal<Direction | undefined>;
30
+ readonly dir: Signal<Direction>;
30
31
  /**
31
32
  * The minimum valid date that can be entered.
32
33
  */
@@ -138,7 +139,7 @@ declare class RdxDateFieldRootDirective {
138
139
  */
139
140
  setFocusedElement(el: HTMLElement): void;
140
141
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxDateFieldRootDirective, never>;
141
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxDateFieldRootDirective, "[rdxDateFieldRoot]", ["rdxDateFieldRoot"], { "value": { "alias": "value"; "required": false; "isSignal": true; }; "isDateUnavailable": { "alias": "isDateUnavailable"; "required": false; "isSignal": true; }; "hourCycle": { "alias": "hourCycle"; "required": false; "isSignal": true; }; "granularity": { "alias": "granularity"; "required": false; "isSignal": true; }; "locale": { "alias": "locale"; "required": false; "isSignal": true; }; "dir": { "alias": "dir"; "required": false; "isSignal": true; }; "minValue": { "alias": "minValue"; "required": false; "isSignal": true; }; "maxValue": { "alias": "maxValue"; "required": false; "isSignal": true; }; "hideTimeZone": { "alias": "hideTimeZone"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "placeholder": "placeholderChange"; }, ["segmentInputs"], never, true, never>;
142
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxDateFieldRootDirective, "[rdxDateFieldRoot]", ["rdxDateFieldRoot"], { "value": { "alias": "value"; "required": false; "isSignal": true; }; "isDateUnavailable": { "alias": "isDateUnavailable"; "required": false; "isSignal": true; }; "hourCycle": { "alias": "hourCycle"; "required": false; "isSignal": true; }; "granularity": { "alias": "granularity"; "required": false; "isSignal": true; }; "locale": { "alias": "locale"; "required": false; "isSignal": true; }; "dirInput": { "alias": "dir"; "required": false; "isSignal": true; }; "minValue": { "alias": "minValue"; "required": false; "isSignal": true; }; "maxValue": { "alias": "maxValue"; "required": false; "isSignal": true; }; "hideTimeZone": { "alias": "hideTimeZone"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "placeholder": "placeholderChange"; }, ["segmentInputs"], never, true, never>;
142
143
  }
143
144
 
144
145
  declare class RdxDateFieldInputDirective {
@@ -3,10 +3,11 @@ import { InjectionToken, Provider, Signal, ElementRef } from '@angular/core';
3
3
  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
- import { RdxTransitionStatus, BooleanInput } from '@radix-ng/primitives/core';
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
- import * as i1$1 from '@radix-ng/primitives/dismissable-layer';
9
- import * as i2 from '@radix-ng/primitives/focus-scope';
10
+ import { RdxOutsidePressDomEvent } from '@radix-ng/primitives/dismissable-layer';
10
11
 
11
12
  /**
12
13
  * Structural directive that teleports the dialog content (backdrop + popup) into a container (default
@@ -81,18 +82,21 @@ declare function provideRdxDialogVariant(variant: Partial<RdxDialogVariant>): Pr
81
82
 
82
83
  type RdxDialogModal = boolean | 'trap-focus';
83
84
  type RdxDialogOpenChangeReason = 'trigger-press' | 'close-press' | 'outside-press' | 'focus-out' | 'escape-key' | 'swipe' | 'imperative-action' | 'none';
85
+ type RdxDialogOpenChangeEventDetails = RdxCancelableChangeEventDetails<RdxDialogOpenChangeReason>;
84
86
  interface RdxDialogOpenChange {
85
87
  open: boolean;
86
88
  triggerId: string | null;
87
89
  trigger: HTMLElement | undefined;
88
90
  reason: RdxDialogOpenChangeReason;
89
91
  event: Event;
92
+ eventDetails: RdxDialogOpenChangeEventDetails;
90
93
  }
91
94
  interface RdxDialogRootContext {
92
95
  contentId: string;
93
96
  titleId: Signal<string | undefined>;
94
97
  descriptionId: Signal<string | undefined>;
95
98
  isOpen: Signal<boolean>;
99
+ present: Signal<boolean>;
96
100
  /** Effective modality (the variant can pin this to `true`). */
97
101
  modal: Signal<RdxDialogModal>;
98
102
  /** Effective outside-press / focus-out dismissal flag (the variant can force it on). */
@@ -103,6 +107,8 @@ interface RdxDialogRootContext {
103
107
  trigger: Signal<HTMLElement | undefined>;
104
108
  triggers: Signal<HTMLElement[]>;
105
109
  payload: Signal<unknown>;
110
+ openInteractionType: Signal<RdxInteractionType>;
111
+ closeInteractionType: Signal<RdxInteractionType>;
106
112
  /** Whether this dialog is nested in another; constant, fixed at construction. */
107
113
  nested: boolean;
108
114
  nestedDialogOpen: Signal<boolean>;
@@ -110,6 +116,7 @@ interface RdxDialogRootContext {
110
116
  setDescriptionId: (id: string | undefined) => void;
111
117
  registerTransitionElement: (element: HTMLElement) => () => void;
112
118
  registerTrigger: (id: string, trigger: HTMLElement, payload: () => unknown) => () => void;
119
+ setTriggerOpenInteractionType: (type: RdxInteractionType) => void;
113
120
  open: (trigger?: HTMLElement, payload?: unknown, triggerId?: string, reason?: RdxDialogOpenChangeReason, event?: Event) => void;
114
121
  close: (reason?: RdxDialogOpenChangeReason, event?: Event) => void;
115
122
  toggle: (triggerId: string, trigger: HTMLElement, payload?: unknown, event?: Event) => void;
@@ -175,6 +182,11 @@ declare class RdxDialogRoot {
175
182
  readonly triggers: _angular_core.WritableSignal<HTMLElement[]>;
176
183
  readonly payload: _angular_core.WritableSignal<unknown>;
177
184
  readonly nestedOpenCount: _angular_core.WritableSignal<number>;
185
+ readonly openInteractionType: _angular_core.WritableSignal<RdxInteractionType>;
186
+ readonly closeInteractionType: _angular_core.WritableSignal<RdxInteractionType>;
187
+ private readonly preventUnmountOnClose;
188
+ private readonly pendingTriggerOpenInteractionType;
189
+ readonly present: Signal<boolean>;
178
190
  /** Whether this dialog is rendered inside another dialog. Fixed at construction. */
179
191
  readonly nested: boolean;
180
192
  readonly nestedDialogOpen: Signal<boolean>;
@@ -184,16 +196,24 @@ declare class RdxDialogRoot {
184
196
  readonly effectiveModal: Signal<RdxDialogModal>;
185
197
  /** Effective dismissal flag: disabled when the input asks, or when the variant forces it (alerts). */
186
198
  readonly effectiveDisablePointerDismissal: Signal<boolean>;
199
+ /**
200
+ * The shared per-popup floating context (ADR 0015 §1) — `open` mirrors the dialog's open state, the
201
+ * trigger registry is bridged from {@link registerTrigger}, and the reference / floating elements are
202
+ * set by the trigger / popup. The new dismissal + focus engines read this once the popup migrates.
203
+ */
204
+ readonly floatingContext: RdxFloatingRootContext;
187
205
  constructor();
188
206
  show(trigger?: HTMLElement | undefined, payload?: unknown, triggerId?: string, reason?: RdxDialogOpenChangeReason, event?: Event): void;
189
207
  close(reason?: RdxDialogOpenChangeReason, event?: Event): void;
190
208
  toggle(triggerId: string, trigger: HTMLElement, payload?: unknown, event?: Event): void;
209
+ setTriggerOpenInteractionType(type: RdxInteractionType): void;
191
210
  registerTrigger(id: string, trigger: HTMLElement, payload: () => unknown): () => void;
192
211
  /** Increments the nested-open counter and returns a release callback that decrements it. */
193
212
  openNestedChild(): () => void;
194
213
  private syncTriggerId;
195
- private emitOpenChange;
214
+ private createOpenChangeEvent;
196
215
  private emitOpenChangeComplete;
216
+ private consumeOpenInteractionType;
197
217
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxDialogRoot, never>;
198
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>;
199
219
  }
@@ -224,19 +244,28 @@ declare class RdxDialogTrigger {
224
244
  protected readonly triggerId: _angular_core.Signal<string>;
225
245
  protected readonly rootContext: _angular_core.Signal<_radix_ng_primitives_dialog.RdxDialogRootContext | null>;
226
246
  protected readonly isOpen: _angular_core.Signal<boolean>;
247
+ protected readonly triggerInteraction: _radix_ng_primitives_floating_focus_manager.RdxTriggerInteraction;
227
248
  constructor();
228
249
  protected handleClick(event: MouseEvent): void;
250
+ protected handlePointerDown(event: PointerEvent): void;
229
251
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxDialogTrigger, never>;
230
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>;
231
253
  }
232
254
 
233
255
  /**
234
256
  * An overlay displayed beneath the dialog popup.
257
+ *
258
+ * Decorative-only, so it carries `role="presentation"` (Base UI `DialogBackdrop`). By default a **nested**
259
+ * dialog renders no backdrop — the parent's already dims the page; stacking a second one double-darkens
260
+ * and intercepts the parent's outside-press. Set `forceRender` to opt back in.
235
261
  */
236
262
  declare class RdxDialogBackdrop {
237
263
  protected readonly rootContext: _radix_ng_primitives_dialog.RdxDialogRootContext;
264
+ /** Render the backdrop even for a nested dialog (off by default, matching Base UI). */
265
+ readonly forceRender: _angular_core.InputSignalWithTransform<boolean, BooleanInput>;
266
+ constructor();
238
267
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxDialogBackdrop, never>;
239
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxDialogBackdrop, "[rdxDialogBackdrop]", ["rdxDialogBackdrop"], {}, {}, never, never, true, never>;
268
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxDialogBackdrop, "[rdxDialogBackdrop]", ["rdxDialogBackdrop"], { "forceRender": { "alias": "forceRender"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
240
269
  }
241
270
 
242
271
  /**
@@ -253,40 +282,67 @@ declare class RdxDialogViewport {
253
282
 
254
283
  /**
255
284
  * A container for the dialog contents.
285
+ *
286
+ * **ADR 0015/0017 Phase-4 migration — Dialog is the PILOT cutover onto the new floating dismissal +
287
+ * focus engine. Browser-verified** by `apps/visual-regression/tests/dialog.behavior.spec.ts` (trap,
288
+ * initial / return focus, Escape / outside-press / focus-out dismissal, nested-Escape deepest-first,
289
+ * backdrop-not-marked).
290
+ *
291
+ * **Mapping (legacy → new):**
292
+ * - `RdxDismissableLayer` (legacy) → `RdxFloatingNodeRegistration` (registers the tree node) +
293
+ * `RdxDismiss` (Escape / outside-press; reads the root context + node).
294
+ * - `RdxFocusScope` (direct) → `RdxFloatingFocusManager` (composes the reworked focus scope; trap +
295
+ * markOthers + close-on-focus-out), driven by `provideFloatingFocusManagerConfig`.
296
+ * - `disableOutsidePointerEvents` → the focus manager's `inert` pass marks outside elements
297
+ * non-interactive for a modal (finding #4), scoped to siblings of the popup's ancestor chain instead
298
+ * of a global `body { pointer-events: none }` lock — so the popup needs no `pointer-events: auto`.
299
+ * - focus-out close moved from the dismissal capability (`focusOutside: () => false`) to the manager
300
+ * (`manager.focusOut`), per ADR 0017 §3.
301
+ * - `isEventOnTrigger` preventDefault → removed: the trigger is in `context.triggers`, so the engine
302
+ * treats a press/focus on it as **inside** (no close-then-reopen).
303
+ *
304
+ * **Parity notes:**
305
+ * - **Lifecycle split (resolved 2026-06-16):** `enabled` is `open || transitionStatus === 'ending'`, so
306
+ * the trap / return-focus machinery survives the exit animation, while the manager's marker + isolation
307
+ * passes additionally key off `open` and release at close-start (Base UI `markOthers` gating).
308
+ * - **`trap-focus` split:** the manager traps focus for `modal === true` and `'trap-focus'`, but applies
309
+ * real `inert` isolation only for `modal === true`, matching Base UI's public contract that
310
+ * `modal="trap-focus"` leaves outside pointer interaction enabled.
311
+ * - **`returnFocus` orchestration (resolved 2026-06-16):** the manager now owns the return-focus *target*
312
+ * via the focus scope's `returnFocus` config seam (the scope owns the *timing* — its queued post-unmount
313
+ * frame). Dialog leaves it at the default (`returnFocus: true` → return to the element focused before
314
+ * open), so behavior is unchanged; a consumer can now also pass `false` / an element / a callback.
256
315
  */
257
316
  declare class RdxDialogPopup {
258
317
  protected readonly rootContext: _radix_ng_primitives_dialog.RdxDialogRootContext;
259
- private readonly dismissableLayer;
318
+ private readonly host;
319
+ private readonly floatingContext;
320
+ private readonly registration;
321
+ private readonly focusManager;
260
322
  private readonly focusScope;
261
- private dismissDetails;
262
- /**
263
- * Event handler called when the escape key is down. Can be prevented.
264
- */
265
- readonly escapeKeyDown: _angular_core.OutputRef<KeyboardEvent>;
266
- /**
267
- * Event handler called when a pointerdown event happens outside of the popup. Can be prevented.
268
- */
269
- readonly pointerDownOutside: _angular_core.OutputRef<PointerEvent>;
270
- /**
271
- * Event handler called when focus moves outside of the popup. Can be prevented.
272
- */
273
- readonly focusOutside: _angular_core.OutputRef<FocusEvent>;
274
- /**
275
- * Event handler called when an interaction happens outside of the popup. Can be prevented.
276
- */
277
- readonly interactOutside: _angular_core.OutputRef<PointerEvent | FocusEvent>;
278
- /**
279
- * Event handler called before focus moves into the popup. Can be prevented.
280
- */
323
+ /** Event handler called when the escape key is down. Can be prevented. */
324
+ readonly escapeKeyDown: _angular_core.OutputEmitterRef<KeyboardEvent>;
325
+ /** Event handler called when a pointerdown event happens outside of the popup. Can be prevented. */
326
+ readonly pointerDownOutside: _angular_core.OutputEmitterRef<RdxOutsidePressDomEvent>;
327
+ /** Event handler called when focus moves outside of the popup. Can be prevented. */
328
+ readonly focusOutside: _angular_core.OutputEmitterRef<FocusEvent>;
329
+ /** Event handler called when an interaction (pointer / focus) happens outside of the popup. */
330
+ readonly interactOutside: _angular_core.OutputEmitterRef<RdxOutsidePressDomEvent | FocusEvent>;
331
+ /** Event handler called before focus moves into the popup. Can be prevented. */
281
332
  readonly openAutoFocus: _angular_core.OutputRef<Event>;
282
- /**
283
- * Event handler called before focus returns after the popup is removed. Can be prevented.
284
- */
333
+ /** Event handler called before focus returns after the popup is removed. Can be prevented. */
285
334
  readonly closeAutoFocus: _angular_core.OutputRef<Event>;
286
335
  constructor();
287
- private isEventOnTrigger;
336
+ /** This dialog is the topmost (deepest open) one — it has no open nested dialog above it. */
337
+ private isTopmost;
338
+ /**
339
+ * Composite navigation keys (arrows / Home / End) are kept inside the dialog (Base UI `DialogPopup`):
340
+ * a dialog opened from inside a Menu / Menubar / Composite must not let an arrow press bubble out and
341
+ * move the outer collection's active item.
342
+ */
343
+ protected onKeyDown(event: KeyboardEvent): void;
288
344
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxDialogPopup, never>;
289
- 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 i1$1.RdxDismissableLayer; inputs: {}; outputs: {}; }, { directive: typeof i2.RdxFocusScope; 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: {}; }]>;
290
346
  }
291
347
 
292
348
  /**
@@ -328,4 +384,4 @@ declare class RdxDialogModule {
328
384
  }
329
385
 
330
386
  export { RDX_DIALOG_VARIANT, RdxDialogBackdrop, RdxDialogClose, RdxDialogDescription, RdxDialogHandle, RdxDialogModule, RdxDialogPopup, RdxDialogPortal, RdxDialogPortalMisuseGuard, RdxDialogRoot, RdxDialogTitle, RdxDialogTrigger, RdxDialogViewport, createRdxDialogHandle, dialogImports, injectRdxDialogRootContext, provideRdxDialogRootContext, provideRdxDialogVariant };
331
- export type { RdxDialogModal, RdxDialogOpenChange, RdxDialogOpenChangeReason, RdxDialogRole, RdxDialogRootContext, RdxDialogVariant };
387
+ export type { RdxDialogModal, RdxDialogOpenChange, RdxDialogOpenChangeEventDetails, RdxDialogOpenChangeReason, RdxDialogRole, RdxDialogRootContext, RdxDialogVariant };
@@ -0,0 +1,41 @@
1
+ import * as _angular_core from '@angular/core';
2
+ import { InjectionToken, Signal, Provider } from '@angular/core';
3
+ import { Direction } from '@radix-ng/primitives/core';
4
+
5
+ type RdxDirectionValue = Direction | Signal<Direction> | (() => Direction);
6
+ declare const RDX_DIRECTION: InjectionToken<Signal<Direction>>;
7
+ /**
8
+ * Provides a primitive behavior direction through Angular DI.
9
+ */
10
+ declare function provideDirection(direction: RdxDirectionValue): Provider;
11
+ /**
12
+ * Provides a reading direction for descendant primitives.
13
+ *
14
+ * This controls primitive behavior only. Set the native `dir` attribute or CSS `direction`
15
+ * separately when the DOM itself should render right-to-left.
16
+ */
17
+ declare class RdxDirectionProvider {
18
+ private readonly parentDirection;
19
+ /**
20
+ * The reading direction for descendant primitives.
21
+ *
22
+ * @defaultValue 'ltr'
23
+ */
24
+ readonly directionInput: _angular_core.InputSignal<Direction | undefined>;
25
+ /** Alias for Angular templates that prefer `[dir]`. */
26
+ readonly dirInput: _angular_core.InputSignal<Direction | undefined>;
27
+ readonly direction: Signal<Direction>;
28
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxDirectionProvider, never>;
29
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxDirectionProvider, "[rdxDirectionProvider]", ["rdxDirectionProvider"], { "directionInput": { "alias": "direction"; "required": false; "isSignal": true; }; "dirInput": { "alias": "dir"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
30
+ }
31
+ /**
32
+ * Reads the effective primitive direction.
33
+ *
34
+ * Priority: explicit local input, nearest DI direction provider, global `provideRadixNG({ dir })`.
35
+ */
36
+ declare function injectDirection(localDirection?: Signal<Direction | undefined>): Signal<Direction>;
37
+
38
+ declare const directionProviderImports: (typeof RdxDirectionProvider)[];
39
+
40
+ export { RDX_DIRECTION, RdxDirectionProvider, directionProviderImports, injectDirection, provideDirection };
41
+ export type { RdxDirectionValue };
@@ -1,6 +1,137 @@
1
- import * as _angular_core from '@angular/core';
2
- import { Signal, InjectionToken, Provider } from '@angular/core';
3
- import { BooleanInput } from '@radix-ng/primitives/core';
1
+ import { RdxFloatingRootContext, RdxFloatingNode, BooleanInput } from '@radix-ng/primitives/core';
2
+ import * as i0 from '@angular/core';
3
+
4
+ /** Why a dismissal was requested — mirrors Base UI's open-change `reason` strings (`useDismiss.ts`). */
5
+ type RdxDismissReason = 'escape-key' | 'outside-press' | 'focus-outside';
6
+ type RdxOutsidePressDomEvent = MouseEvent | PointerEvent | TouchEvent;
7
+ /**
8
+ * Configuration for {@link RdxDismiss}. Every flag is a getter so it can be a signal
9
+ * read (reactive) or a plain predicate. The `on*` pre-hooks are **preventable**: call
10
+ * `event.preventDefault()` inside one to veto that dismissal (the layer then stays open).
11
+ */
12
+ /** When an outside press dismisses: `'sloppy'` closes on `pointerdown`, `'intentional'` on `click`. */
13
+ type RdxOutsidePressEvent = 'sloppy' | 'intentional';
14
+ /**
15
+ * `outsidePressEvent` config (Base UI). Either a single mode for every pointer type, or a per-pointer-type
16
+ * map (`{ mouse, touch, pen }`) resolved against the pointer type of the active press. A missing key falls
17
+ * back to `'sloppy'`.
18
+ */
19
+ type RdxOutsidePressEventConfig = RdxOutsidePressEvent | {
20
+ mouse?: RdxOutsidePressEvent;
21
+ touch?: RdxOutsidePressEvent;
22
+ pen?: RdxOutsidePressEvent;
23
+ };
24
+ interface RdxDismissProps {
25
+ /** Whole-capability gate (on top of `context.open()`). Default `() => true`. */
26
+ enabled?: () => boolean;
27
+ /** Whether Escape requests dismissal. Default `() => true`. */
28
+ escapeKey?: () => boolean;
29
+ /**
30
+ * Whether this layer's Escape **bubbles** to ancestor layers (Base UI `bubbles.escapeKey`). Default
31
+ * `() => false` — Escape closes only the deepest layer. `true` re-emits to the parent too (this is
32
+ * Menu's `closeParentOnEsc`: a submenu's Escape also closes the parent menu).
33
+ */
34
+ escapeKeyBubbles?: () => boolean;
35
+ /**
36
+ * Whether an outside pointer press requests dismissal. Default `() => true`. Receives the press
37
+ * **event**, so a layer can decide per target / button / pointer (e.g. Dialog: only the topmost
38
+ * dialog dismisses; only its own backdrop counts).
39
+ */
40
+ outsidePress?: (event: Event) => boolean;
41
+ /**
42
+ * When an outside press dismisses (Base UI `outsidePressEvent`). `'sloppy'` (default) closes on
43
+ * `pointerdown` — immediate, OS-like. `'intentional'` closes on `click` — requires a full
44
+ * press-and-release on the same outside target, and suppresses the click when the press **started
45
+ * inside** (so selecting text and dragging out does not dismiss). May be a per-pointer-type map
46
+ * resolved against the active press (`{ mouse: 'intentional', touch: 'sloppy' }`).
47
+ */
48
+ outsidePressEvent?: () => RdxOutsidePressEventConfig;
49
+ /**
50
+ * Whether this layer's outside-press **bubbles** to ancestor layers (Base UI `bubbles.outsidePress`).
51
+ * Default `() => true` — an outside press closes the whole stack. `false` makes an open non-bubbling
52
+ * child block the parent (only the deepest closes).
53
+ */
54
+ outsidePressBubbles?: () => boolean;
55
+ /** Whether focus leaving the layer requests dismissal. Default `() => true`. */
56
+ focusOutside?: () => boolean;
57
+ /** Preventable pre-hook for Escape. */
58
+ onEscapeKeyDown?: (event: KeyboardEvent) => void;
59
+ /** Preventable pre-hook for an outside pointer press. */
60
+ onPointerDownOutside?: (event: RdxOutsidePressDomEvent) => void;
61
+ /** Preventable pre-hook for focus moving outside. */
62
+ onFocusOutside?: (event: FocusEvent) => void;
63
+ /** Called when a non-prevented dismissal is requested. */
64
+ onDismiss?: (reason: RdxDismissReason, event: Event) => void;
65
+ }
66
+ /**
67
+ * The **dismiss** mechanism (ADR 0015) — the Angular counterpart of Base UI's `useDismiss`. It
68
+ * **references** a {@link RdxFloatingRootContext} (mandatory: `open` / `triggers` / elements live there)
69
+ * and a {@link RdxFloatingNode} (**optional**: a node-optional / Navigation-Menu state has `node ===
70
+ * null`); it never creates them. It listens for Escape / outside-press / focus-out and **requests** a
71
+ * dismissal via `onDismiss` when an interaction lands outside the logical layer and this layer owns the
72
+ * event.
73
+ *
74
+ * **Logical, not DOM-order, containment.** "Inside" is resolved through the shared tree — this popup's
75
+ * floating element + its registered triggers, **plus** the same for every open descendant node, **plus**
76
+ * this layer's own {@link branches}. So a portal-relocated child still counts as inside its parent — which
77
+ * a DOM-order containment check cannot do.
78
+ *
79
+ * **Ownership & propagation (`hasBlockingChild`).** Each layer publishes per-event `bubbles` flags
80
+ * (`escapeKeyBubbles` default `false`, `outsidePressBubbles` default `true`); an ancestor reads its open
81
+ * children's flags via {@link childBubbles}. A non-bubbling layer **yields** to a non-bubbling open child,
82
+ * so by default Escape closes only the **deepest** layer while an outside press closes the **whole stack**.
83
+ * A layer with `escapeKeyBubbles = true` re-emits to its parent (Menu's `closeParentOnEsc`). The owning
84
+ * non-bubbling Escape layer also `stopPropagation()`s so the key does not reach app handlers.
85
+ *
86
+ * **Press / IME hardening.** Outside-press honors `outsidePressEvent` (`'sloppy'` → `pointerdown`,
87
+ * `'intentional'` → `click` with press-start-inside drag-out suppression), ignores non-primary mouse
88
+ * buttons and scrollbar presses, resets on `pointercancel`, and ignores Escape while an IME composition is
89
+ * active. **Touch** sloppy-mode gesture hardening (long-press / drag-distance thresholds) is ported here
90
+ * but only unit-exercisable via synthetic events — real on-device behavior is covered by
91
+ * `apps/visual-regression` (Playwright).
92
+ *
93
+ * **Scope.** Must be constructed in an injection context (`DestroyRef` / `PLATFORM_ID`). No-op on the
94
+ * server.
95
+ */
96
+ declare class RdxDismiss {
97
+ readonly context: RdxFloatingRootContext;
98
+ readonly node: () => RdxFloatingNode | null;
99
+ /** This layer's own inside-content set (branches that live outside the popup DOM). */
100
+ readonly branches: Set<Element>;
101
+ /** This mechanism's active-ness: the popup is open **and** dismissal is enabled. */
102
+ readonly active: () => boolean;
103
+ constructor(context: RdxFloatingRootContext, node: () => RdxFloatingNode | null, config?: RdxDismissProps);
104
+ /**
105
+ * Whether `target` is logically inside this layer: within this popup's floating element or one of its
106
+ * registered triggers, within any **open descendant** node's floating element / triggers, or within a
107
+ * registered branch.
108
+ */
109
+ private isInside;
110
+ /** `target` is inside a context's floating element or one of its registered triggers. */
111
+ private contextContains;
112
+ /**
113
+ * Whether an open descendant blocks this layer for `reason` (so it should yield). A child blocks when
114
+ * it does **not** let the event bubble past it ({@link childBubbles} is `false`). Base UI's
115
+ * `hasBlockingChild` (`useDismiss.ts:170`) is a capability-local function — **not** a tree method — so
116
+ * the tree stays neutral.
117
+ */
118
+ private hasBlockingChild;
119
+ }
120
+
121
+ /**
122
+ * Marks its host as **inside** the enclosing floating layer (ADR 0015): a pointer / focus interaction on
123
+ * it does not count as "outside", so it never dismisses the popup. It registers the host into the
124
+ * floating root context's trigger registry — {@link RdxDismiss}'s `isInside` check reads it.
125
+ *
126
+ * Use it for an element that lives **outside** the popup DOM but logically belongs to the layer — e.g. a
127
+ * Combobox input / trigger / chips / clear button that keeps focus (or is clicked) while the listbox is
128
+ * open.
129
+ */
130
+ declare class RdxFloatingInsideElement {
131
+ constructor();
132
+ static ɵfac: i0.ɵɵFactoryDeclaration<RdxFloatingInsideElement, never>;
133
+ static ɵdir: i0.ɵɵDirectiveDeclaration<RdxFloatingInsideElement, "[rdxFloatingInside]", ["rdxFloatingInside"], {}, {}, never, never, true, never>;
134
+ }
4
135
 
5
136
  /**
6
137
  * Listens for when focus happens outside a DOM subtree.
@@ -8,16 +139,16 @@ import { BooleanInput } from '@radix-ng/primitives/core';
8
139
  */
9
140
  declare class RdxFocusOutside {
10
141
  #private;
11
- readonly enabledInput: _angular_core.InputSignalWithTransform<boolean, BooleanInput>;
142
+ readonly enabledInput: i0.InputSignalWithTransform<boolean, BooleanInput>;
12
143
  set enabled(value: boolean);
13
144
  get enabled(): boolean;
14
- readonly focusOutside: _angular_core.OutputEmitterRef<FocusEvent>;
145
+ readonly focusOutside: i0.OutputEmitterRef<FocusEvent>;
15
146
  private readonly isFocusInsideDOMTree;
16
147
  private readonly focusCaptureHandler;
17
148
  private readonly blurCaptureHandler;
18
149
  constructor();
19
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxFocusOutside, never>;
20
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxFocusOutside, "[rdxFocusOutside]", ["rdxFocusOutside"], { "enabledInput": { "alias": "enabled"; "required": false; "isSignal": true; }; }, { "focusOutside": "focusOutside"; }, never, never, true, never>;
150
+ static ɵfac: i0.ɵɵFactoryDeclaration<RdxFocusOutside, never>;
151
+ static ɵdir: i0.ɵɵDirectiveDeclaration<RdxFocusOutside, "[rdxFocusOutside]", ["rdxFocusOutside"], { "enabledInput": { "alias": "enabled"; "required": false; "isSignal": true; }; }, { "focusOutside": "focusOutside"; }, never, never, true, never>;
21
152
  }
22
153
  /**
23
154
  * Listens for `pointerdown` outside a DOM subtree. We use `pointerdown` rather than `pointerup`
@@ -27,108 +158,25 @@ declare class RdxFocusOutside {
27
158
  declare class RdxPointerDownOutside {
28
159
  #private;
29
160
  private readonly elementRef;
30
- readonly enabledInput: _angular_core.InputSignalWithTransform<boolean, BooleanInput>;
161
+ readonly enabledInput: i0.InputSignalWithTransform<boolean, BooleanInput>;
31
162
  set enabled(value: boolean);
32
163
  get enabled(): boolean;
33
- readonly pointerDownOutside: _angular_core.OutputEmitterRef<PointerEvent>;
164
+ readonly pointerDownOutside: i0.OutputEmitterRef<PointerEvent>;
34
165
  private readonly isPointerInsideDOMTree;
35
166
  private readonly handleAndDispatchPointerDownOutsideEvent;
36
167
  private handleClick?;
37
168
  constructor();
38
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxPointerDownOutside, never>;
39
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxPointerDownOutside, "[rdxPointerDownOutside]", ["rdxPointerDownOutside"], { "enabledInput": { "alias": "enabled"; "required": false; "isSignal": true; }; }, { "pointerDownOutside": "pointerDownOutside"; }, never, never, true, never>;
169
+ static ɵfac: i0.ɵɵFactoryDeclaration<RdxPointerDownOutside, never>;
170
+ static ɵdir: i0.ɵɵDirectiveDeclaration<RdxPointerDownOutside, "[rdxPointerDownOutside]", ["rdxPointerDownOutside"], { "enabledInput": { "alias": "enabled"; "required": false; "isSignal": true; }; }, { "pointerDownOutside": "pointerDownOutside"; }, never, never, true, never>;
40
171
  }
41
172
  declare class RdxEscapeKeyDown {
42
173
  private readonly elementRef;
43
174
  private readonly destroyRef;
44
- readonly escapeKeyDown: _angular_core.OutputEmitterRef<KeyboardEvent>;
175
+ readonly escapeKeyDown: i0.OutputEmitterRef<KeyboardEvent>;
45
176
  constructor();
46
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxEscapeKeyDown, never>;
47
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxEscapeKeyDown, "[rdxEscapeKeyDown]", ["rdxEscapeKeyDown"], {}, { "escapeKeyDown": "escapeKeyDown"; }, never, never, true, never>;
177
+ static ɵfac: i0.ɵɵFactoryDeclaration<RdxEscapeKeyDown, never>;
178
+ static ɵdir: i0.ɵɵDirectiveDeclaration<RdxEscapeKeyDown, "[rdxEscapeKeyDown]", ["rdxEscapeKeyDown"], {}, { "escapeKeyDown": "escapeKeyDown"; }, never, never, true, never>;
48
179
  }
49
180
 
50
- declare class RdxDismissableLayer {
51
- private readonly elementRef;
52
- private readonly injector;
53
- private readonly destroyRef;
54
- private readonly context;
55
- private readonly config;
56
- private readonly rdxPointerDownOutside;
57
- private readonly rdxFocusOutside;
58
- private readonly rdxEscapeKeyDown;
59
- /**
60
- * Event handler called when the escape key is down.
61
- * Can be prevented.
62
- */
63
- readonly escapeKeyDown: _angular_core.OutputEmitterRef<KeyboardEvent>;
64
- /**
65
- * Event handler called when a `pointerdown` event happens outside of the `DismissableLayer`.
66
- * Can be prevented.
67
- */
68
- readonly pointerDownOutside: _angular_core.OutputEmitterRef<PointerEvent>;
69
- /**
70
- * Event handler called when the focus moves outside of the `DismissableLayer`.
71
- * Can be prevented.
72
- */
73
- readonly focusOutside: _angular_core.OutputEmitterRef<FocusEvent>;
74
- /**
75
- * Event handler called when an interaction happens outside the `DismissableLayer`.
76
- * Specifically, when a `pointerdown` event happens outside or focus moves outside of it.
77
- * Can be prevented.
78
- */
79
- readonly interactOutside: _angular_core.OutputEmitterRef<FocusEvent | PointerEvent>;
80
- /**
81
- * Handler called when the `DismissableLayer` should be dismissed
82
- */
83
- readonly dismiss: _angular_core.OutputEmitterRef<void>;
84
- /**
85
- * When `true`, hover/focus/click interactions will be disabled on elements outside
86
- * the `DismissableLayer`. Users will need to click twice on outside elements to
87
- * interact with them: once to close the `DismissableLayer`, and again to trigger the element.
88
- */
89
- readonly disableOutsidePointerEvents: _angular_core.InputSignalWithTransform<boolean | undefined, BooleanInput>;
90
- readonly isOutsidePointerEventsDisabled: _angular_core.Signal<boolean>;
91
- protected readonly isBodyPointerEventsDisabled: _angular_core.Signal<boolean>;
92
- protected readonly isPointerEventsEnabled: _angular_core.Signal<boolean>;
93
- private readonly index;
94
- /** The topmost layer in the stack — the only one that should react to the Escape key. */
95
- private readonly isHighestLayer;
96
- constructor();
97
- /**
98
- * Toggles `pointer-events: none` on the document body while any layer has
99
- * `disableOutsidePointerEvents`. Ownership is shared across all layers via
100
- * {@link originalBodyPointerEvents}: the original value is saved only on the global
101
- * `0 -> >0` transition and restored only when the count returns to `0`.
102
- */
103
- private setupBodyPointerEvents;
104
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxDismissableLayer, never>;
105
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxDismissableLayer, "[rdxDismissableLayer]", ["rdxDismissableLayer"], { "disableOutsidePointerEvents": { "alias": "disableOutsidePointerEvents"; "required": false; "isSignal": true; }; }, { "escapeKeyDown": "escapeKeyDown"; "pointerDownOutside": "pointerDownOutside"; "focusOutside": "focusOutside"; "interactOutside": "interactOutside"; "dismiss": "dismiss"; }, never, never, true, [{ directive: typeof RdxPointerDownOutside; inputs: {}; outputs: {}; }, { directive: typeof RdxFocusOutside; inputs: {}; outputs: {}; }, { directive: typeof RdxEscapeKeyDown; inputs: {}; outputs: {}; }]>;
106
- }
107
-
108
- declare class RdxDismissableLayerBranch {
109
- private readonly elementRef;
110
- private readonly destroyRef;
111
- private readonly dismissableLayersContext;
112
- constructor();
113
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxDismissableLayerBranch, never>;
114
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxDismissableLayerBranch, "[rdxDismissableLayerBranch]", never, {}, {}, never, never, true, never>;
115
- }
116
-
117
- declare const RdxDismissableLayersContextToken: InjectionToken<{
118
- layersRoot: _angular_core.WritableSignal<RdxDismissableLayer[]>;
119
- layersWithOutsidePointerEventsDisabled: Signal<RdxDismissableLayer[]>;
120
- branches: _angular_core.WritableSignal<HTMLElement[]>;
121
- }>;
122
- type RdxDismissableLayerConfig = {
123
- /**
124
- * When `true`, hover/focus/click interactions will be disabled on elements outside
125
- * the `DismissableLayer`. Users will need to click twice on outside elements to
126
- * interact with them: once to close the `DismissableLayer`, and again to trigger the element.
127
- */
128
- disableOutsidePointerEvents: Signal<boolean>;
129
- };
130
- declare const RdxDismissableLayerConfigToken: InjectionToken<RdxDismissableLayerConfig>;
131
- declare function provideRdxDismissableLayerConfig(factory: () => RdxDismissableLayerConfig): Provider;
132
-
133
- export { RdxDismissableLayer, RdxDismissableLayerBranch, RdxDismissableLayerConfigToken, RdxDismissableLayersContextToken, RdxEscapeKeyDown, RdxFocusOutside, RdxPointerDownOutside, provideRdxDismissableLayerConfig };
134
- export type { RdxDismissableLayerConfig };
181
+ export { RdxDismiss, RdxEscapeKeyDown, RdxFloatingInsideElement, RdxFocusOutside, RdxPointerDownOutside };
182
+ export type { RdxDismissProps, RdxDismissReason, RdxOutsidePressDomEvent, RdxOutsidePressEvent, RdxOutsidePressEventConfig };
@@ -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 };
@@ -188,6 +188,7 @@ declare class RdxFieldLabel {
188
188
  */
189
189
  readonly id: _angular_core.InputSignal<string>;
190
190
  readonly htmlFor: () => string;
191
+ constructor();
191
192
  protected readonly dataAttr: (value: boolean) => "" | undefined;
192
193
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RdxFieldLabel, never>;
193
194
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RdxFieldLabel, "[rdxFieldLabel]", ["rdxFieldLabel"], { "id": { "alias": "id"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;