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

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 (104) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +76 -6
  3. package/fesm2022/radix-ng-primitives-accordion.mjs +5 -3
  4. package/fesm2022/radix-ng-primitives-accordion.mjs.map +1 -1
  5. package/fesm2022/radix-ng-primitives-alert-dialog.mjs +31 -24
  6. package/fesm2022/radix-ng-primitives-alert-dialog.mjs.map +1 -1
  7. package/fesm2022/radix-ng-primitives-autocomplete.mjs +1744 -0
  8. package/fesm2022/radix-ng-primitives-autocomplete.mjs.map +1 -0
  9. package/fesm2022/radix-ng-primitives-calendar.mjs +5 -3
  10. package/fesm2022/radix-ng-primitives-calendar.mjs.map +1 -1
  11. package/fesm2022/radix-ng-primitives-combobox.mjs +1399 -606
  12. package/fesm2022/radix-ng-primitives-combobox.mjs.map +1 -1
  13. package/fesm2022/radix-ng-primitives-config.mjs +13 -4
  14. package/fesm2022/radix-ng-primitives-config.mjs.map +1 -1
  15. package/fesm2022/radix-ng-primitives-context-menu.mjs +51 -10
  16. package/fesm2022/radix-ng-primitives-context-menu.mjs.map +1 -1
  17. package/fesm2022/radix-ng-primitives-core.mjs +1345 -64
  18. package/fesm2022/radix-ng-primitives-core.mjs.map +1 -1
  19. package/fesm2022/radix-ng-primitives-date-field.mjs +5 -3
  20. package/fesm2022/radix-ng-primitives-date-field.mjs.map +1 -1
  21. package/fesm2022/radix-ng-primitives-dialog.mjs +271 -145
  22. package/fesm2022/radix-ng-primitives-dialog.mjs.map +1 -1
  23. package/fesm2022/radix-ng-primitives-direction-provider.mjs +70 -0
  24. package/fesm2022/radix-ng-primitives-direction-provider.mjs.map +1 -0
  25. package/fesm2022/radix-ng-primitives-dismissable-layer.mjs +519 -184
  26. package/fesm2022/radix-ng-primitives-dismissable-layer.mjs.map +1 -1
  27. package/fesm2022/radix-ng-primitives-drawer.mjs +154 -64
  28. package/fesm2022/radix-ng-primitives-drawer.mjs.map +1 -1
  29. package/fesm2022/radix-ng-primitives-field.mjs +3 -2
  30. package/fesm2022/radix-ng-primitives-field.mjs.map +1 -1
  31. package/fesm2022/radix-ng-primitives-floating-focus-manager.mjs +517 -0
  32. package/fesm2022/radix-ng-primitives-floating-focus-manager.mjs.map +1 -0
  33. package/fesm2022/radix-ng-primitives-focus-scope.mjs +296 -70
  34. package/fesm2022/radix-ng-primitives-focus-scope.mjs.map +1 -1
  35. package/fesm2022/radix-ng-primitives-menu.mjs +894 -299
  36. package/fesm2022/radix-ng-primitives-menu.mjs.map +1 -1
  37. package/fesm2022/radix-ng-primitives-menubar.mjs +32 -4
  38. package/fesm2022/radix-ng-primitives-menubar.mjs.map +1 -1
  39. package/fesm2022/radix-ng-primitives-navigation-menu.mjs +176 -207
  40. package/fesm2022/radix-ng-primitives-navigation-menu.mjs.map +1 -1
  41. package/fesm2022/radix-ng-primitives-popover.mjs +250 -250
  42. package/fesm2022/radix-ng-primitives-popover.mjs.map +1 -1
  43. package/fesm2022/radix-ng-primitives-popper.mjs +94 -45
  44. package/fesm2022/radix-ng-primitives-popper.mjs.map +1 -1
  45. package/fesm2022/radix-ng-primitives-portal.mjs +107 -17
  46. package/fesm2022/radix-ng-primitives-portal.mjs.map +1 -1
  47. package/fesm2022/radix-ng-primitives-presence.mjs +262 -79
  48. package/fesm2022/radix-ng-primitives-presence.mjs.map +1 -1
  49. package/fesm2022/radix-ng-primitives-preview-card.mjs +172 -218
  50. package/fesm2022/radix-ng-primitives-preview-card.mjs.map +1 -1
  51. package/fesm2022/radix-ng-primitives-roving-focus.mjs +4 -2
  52. package/fesm2022/radix-ng-primitives-roving-focus.mjs.map +1 -1
  53. package/fesm2022/radix-ng-primitives-scroll-area.mjs +5 -4
  54. package/fesm2022/radix-ng-primitives-scroll-area.mjs.map +1 -1
  55. package/fesm2022/radix-ng-primitives-select.mjs +303 -234
  56. package/fesm2022/radix-ng-primitives-select.mjs.map +1 -1
  57. package/fesm2022/radix-ng-primitives-slider.mjs +5 -3
  58. package/fesm2022/radix-ng-primitives-slider.mjs.map +1 -1
  59. package/fesm2022/radix-ng-primitives-stepper.mjs +5 -3
  60. package/fesm2022/radix-ng-primitives-stepper.mjs.map +1 -1
  61. package/fesm2022/radix-ng-primitives-time-field.mjs +5 -3
  62. package/fesm2022/radix-ng-primitives-time-field.mjs.map +1 -1
  63. package/fesm2022/radix-ng-primitives-toast.mjs +15 -36
  64. package/fesm2022/radix-ng-primitives-toast.mjs.map +1 -1
  65. package/fesm2022/radix-ng-primitives-toggle-group.mjs +5 -3
  66. package/fesm2022/radix-ng-primitives-toggle-group.mjs.map +1 -1
  67. package/fesm2022/radix-ng-primitives-toolbar.mjs +5 -3
  68. package/fesm2022/radix-ng-primitives-toolbar.mjs.map +1 -1
  69. package/fesm2022/radix-ng-primitives-tooltip.mjs +105 -145
  70. package/fesm2022/radix-ng-primitives-tooltip.mjs.map +1 -1
  71. package/package.json +14 -1
  72. package/types/radix-ng-primitives-accordion.d.ts +4 -3
  73. package/types/radix-ng-primitives-alert-dialog.d.ts +17 -11
  74. package/types/radix-ng-primitives-autocomplete.d.ts +661 -0
  75. package/types/radix-ng-primitives-calendar.d.ts +5 -3
  76. package/types/radix-ng-primitives-combobox.d.ts +727 -293
  77. package/types/radix-ng-primitives-config.d.ts +1 -1
  78. package/types/radix-ng-primitives-context-menu.d.ts +15 -5
  79. package/types/radix-ng-primitives-core.d.ts +762 -14
  80. package/types/radix-ng-primitives-date-field.d.ts +3 -2
  81. package/types/radix-ng-primitives-dialog.d.ts +107 -55
  82. package/types/radix-ng-primitives-direction-provider.d.ts +41 -0
  83. package/types/radix-ng-primitives-dismissable-layer.d.ts +147 -99
  84. package/types/radix-ng-primitives-drawer.d.ts +49 -22
  85. package/types/radix-ng-primitives-field.d.ts +1 -0
  86. package/types/radix-ng-primitives-floating-focus-manager.d.ts +175 -0
  87. package/types/radix-ng-primitives-focus-scope.d.ts +132 -1
  88. package/types/radix-ng-primitives-menu.d.ts +204 -112
  89. package/types/radix-ng-primitives-navigation-menu.d.ts +61 -101
  90. package/types/radix-ng-primitives-popover.d.ts +82 -115
  91. package/types/radix-ng-primitives-popper.d.ts +46 -10
  92. package/types/radix-ng-primitives-portal.d.ts +53 -8
  93. package/types/radix-ng-primitives-presence.d.ts +98 -17
  94. package/types/radix-ng-primitives-preview-card.d.ts +63 -95
  95. package/types/radix-ng-primitives-roving-focus.d.ts +7 -6
  96. package/types/radix-ng-primitives-scroll-area.d.ts +2 -2
  97. package/types/radix-ng-primitives-select.d.ts +192 -158
  98. package/types/radix-ng-primitives-slider.d.ts +5 -4
  99. package/types/radix-ng-primitives-stepper.d.ts +4 -3
  100. package/types/radix-ng-primitives-time-field.d.ts +3 -2
  101. package/types/radix-ng-primitives-toast.d.ts +7 -7
  102. package/types/radix-ng-primitives-toggle-group.d.ts +5 -4
  103. package/types/radix-ng-primitives-toolbar.d.ts +3 -2
  104. package/types/radix-ng-primitives-tooltip.d.ts +48 -84
@@ -1,8 +1,8 @@
1
1
  import * as i0 from '@angular/core';
2
- import { signal, computed, Injectable, Directive, inject, input, model, booleanAttribute, output, effect, untracked, assertInInjectionContext, DestroyRef, ElementRef, Injector, NgModule } from '@angular/core';
2
+ import { signal, computed, Injectable, Directive, inject, input, model, booleanAttribute, output, effect, untracked, assertInInjectionContext, DestroyRef, ElementRef, Injector, isDevMode, NgModule } from '@angular/core';
3
3
  import * as i1 from '@radix-ng/primitives/dialog';
4
- import { RdxDialogRoot, RdxDialogBackdrop, RdxDialogClose, RdxDialogDescription, injectRdxDialogRootContext, RdxDialogPopup, RdxDialogPortal, RdxDialogPortalPresence, RdxDialogTitle, RdxDialogTrigger, RdxDialogViewport, RdxDialogHandle, createRdxDialogHandle } from '@radix-ng/primitives/dialog';
5
- import { createContext, clamp, usePointerDrag, elementSize } from '@radix-ng/primitives/core';
4
+ import { RdxDialogRoot, RdxDialogBackdrop, RdxDialogClose, RdxDialogDescription, injectRdxDialogRootContext, RdxDialogPopup, RdxDialogPortal, RdxDialogTitle, RdxDialogTrigger, RdxDialogViewport, RdxDialogHandle, createRdxDialogHandle } from '@radix-ng/primitives/dialog';
5
+ import { createContext, clamp, usePointerDrag, elementSize, rdxDevError } from '@radix-ng/primitives/core';
6
6
  export { usePointerDrag } from '@radix-ng/primitives/core';
7
7
 
8
8
  /**
@@ -22,6 +22,8 @@ class RdxDrawerProvider {
22
22
  this.frontmost = computed(() => this.stack().at(-1) ?? null, ...(ngDevMode ? [{ debugName: "frontmost" }] : /* istanbul ignore next */ []));
23
23
  /** The frontmost drawer's measured size (px), or `0` when none is open. */
24
24
  this.frontmostHeight = computed(() => this.frontmost()?.height() ?? 0, ...(ngDevMode ? [{ debugName: "frontmostHeight" }] : /* istanbul ignore next */ []));
25
+ /** The frontmost drawer's live dismiss progress, or `0` when none is open. */
26
+ this.swipeProgress = computed(() => this.frontmost()?.swipeProgress() ?? 0, ...(ngDevMode ? [{ debugName: "swipeProgress" }] : /* istanbul ignore next */ []));
25
27
  }
26
28
  /** Register an open drawer; returns a disposer that removes it. */
27
29
  register(registration) {
@@ -62,6 +64,12 @@ const context = () => {
62
64
  swipeDirection: root.swipeDirection,
63
65
  swipeProgress: root.swipeProgress.asReadonly(),
64
66
  setSwipeProgress: (value) => root.swipeProgress.set(value),
67
+ openingSwipeActive: root.openingSwipeActive.asReadonly(),
68
+ openingSwipeDistance: root.openingSwipeDistance.asReadonly(),
69
+ setOpeningSwipe: (active, distance) => {
70
+ root.openingSwipeDistance.set(distance);
71
+ root.openingSwipeActive.set(active);
72
+ },
65
73
  snapPoints: root.normalizedSnapPoints,
66
74
  hasSnapPoints: root.hasSnapPoints,
67
75
  activeSnapPoint: root.snapPoint,
@@ -95,12 +103,12 @@ class RdxDrawerRoot {
95
103
  this.swipeDirection = input('down', ...(ngDevMode ? [{ debugName: "swipeDirection" }] : /* istanbul ignore next */ []));
96
104
  /**
97
105
  * Resting positions the drawer snaps to along the dismiss axis. Order ascending by openness; the
98
- * last entry is the default the drawer opens to. Omit for a plain open/closed drawer.
106
+ * first entry is the default the drawer opens to. Omit for a plain open/closed drawer.
99
107
  */
100
108
  this.snapPoints = input(...(ngDevMode ? [undefined, { debugName: "snapPoints" }] : /* istanbul ignore next */ []));
101
109
  /** The active snap point (controlled / uncontrolled with `[(snapPoint)]`). */
102
110
  this.snapPoint = model(null, ...(ngDevMode ? [{ debugName: "snapPoint" }] : /* istanbul ignore next */ []));
103
- /** The snap point the drawer opens to when uncontrolled; defaults to the most open point. */
111
+ /** The snap point the drawer opens to when uncontrolled; defaults to the first point. */
104
112
  this.defaultSnapPoint = input(...(ngDevMode ? [undefined, { debugName: "defaultSnapPoint" }] : /* istanbul ignore next */ []));
105
113
  /** Step at most one snap point per release instead of letting velocity skip points. */
106
114
  this.snapToSequentialPoints = input(false, { ...(ngDevMode ? { debugName: "snapToSequentialPoints" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
@@ -108,6 +116,9 @@ class RdxDrawerRoot {
108
116
  this.onSnapPointChange = output();
109
117
  /** 0..1 progress of the active dismiss gesture, written by the popup's swipe engine. */
110
118
  this.swipeProgress = signal(0, ...(ngDevMode ? [{ debugName: "swipeProgress" }] : /* istanbul ignore next */ []));
119
+ /** Live SwipeArea reveal state; the popup converts distance into its measured-axis movement. */
120
+ this.openingSwipeActive = signal(false, ...(ngDevMode ? [{ debugName: "openingSwipeActive" }] : /* istanbul ignore next */ []));
121
+ this.openingSwipeDistance = signal(0, ...(ngDevMode ? [{ debugName: "openingSwipeDistance" }] : /* istanbul ignore next */ []));
111
122
  this.normalizedSnapPoints = computed(() => this.snapPoints() ?? [], ...(ngDevMode ? [{ debugName: "normalizedSnapPoints" }] : /* istanbul ignore next */ []));
112
123
  this.hasSnapPoints = computed(() => this.normalizedSnapPoints().length > 0, ...(ngDevMode ? [{ debugName: "hasSnapPoints" }] : /* istanbul ignore next */ []));
113
124
  /** Whether a drawer nested inside this one is open (reuses the dialog's nesting detection). */
@@ -130,20 +141,28 @@ class RdxDrawerRoot {
130
141
  untracked(() => {
131
142
  const points = this.normalizedSnapPoints();
132
143
  if (open && this.snapPoint() === null && points.length > 0) {
133
- this.snapPoint.set(this.defaultSnapPoint() ?? points[points.length - 1]);
144
+ this.snapPoint.set(this.defaultSnapPoint() ?? points[0]);
134
145
  }
135
146
  });
136
147
  });
137
148
  // Reset live swipe progress when closed so a reopened drawer never starts mid-gesture.
138
149
  effect(() => {
139
150
  if (!this.dialog.open()) {
140
- untracked(() => this.swipeProgress.set(0));
151
+ untracked(() => {
152
+ this.swipeProgress.set(0);
153
+ this.openingSwipeActive.set(false);
154
+ this.openingSwipeDistance.set(0);
155
+ });
141
156
  }
142
157
  });
143
158
  // Register with the optional app-level provider while open so background content can react.
144
159
  effect((onCleanup) => {
145
160
  if (this.dialog.open() && this.provider) {
146
- onCleanup(untracked(() => this.provider.register({ id: this.dialog.contentId, height: this.popupHeight.asReadonly() })));
161
+ onCleanup(untracked(() => this.provider.register({
162
+ id: this.dialog.contentId,
163
+ height: this.popupHeight.asReadonly(),
164
+ swipeProgress: this.swipeProgress.asReadonly()
165
+ })));
147
166
  }
148
167
  });
149
168
  }
@@ -191,7 +210,7 @@ class RdxDrawerBackdrop {
191
210
  this.drawerContext = injectRdxDrawerRootContext();
192
211
  }
193
212
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerBackdrop, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
194
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxDrawerBackdrop, isStandalone: true, selector: "[rdxDrawerBackdrop]", host: { properties: { "style.--drawer-swipe-progress": "drawerContext.swipeProgress()", "attr.data-nested-drawer-open": "drawerContext.nestedDrawerOpen() ? \"\" : undefined" } }, exportAs: ["rdxDrawerBackdrop"], hostDirectives: [{ directive: i1.RdxDialogBackdrop }], ngImport: i0 }); }
213
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxDrawerBackdrop, isStandalone: true, selector: "[rdxDrawerBackdrop]", host: { properties: { "style.--drawer-swipe-progress": "drawerContext.swipeProgress()", "attr.data-swiping": "drawerContext.openingSwipeActive() ? \"\" : undefined", "attr.data-nested-drawer-open": "drawerContext.nestedDrawerOpen() ? \"\" : undefined" } }, exportAs: ["rdxDrawerBackdrop"], hostDirectives: [{ directive: i1.RdxDialogBackdrop }], ngImport: i0 }); }
195
214
  }
196
215
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerBackdrop, decorators: [{
197
216
  type: Directive,
@@ -201,6 +220,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
201
220
  hostDirectives: [RdxDialogBackdrop],
202
221
  host: {
203
222
  '[style.--drawer-swipe-progress]': 'drawerContext.swipeProgress()',
223
+ '[attr.data-swiping]': 'drawerContext.openingSwipeActive() ? "" : undefined',
204
224
  '[attr.data-nested-drawer-open]': 'drawerContext.nestedDrawerOpen() ? "" : undefined'
205
225
  }
206
226
  }]
@@ -264,6 +284,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
264
284
  * Reads the nearest {@link RdxDrawerProvider} and exposes styling hooks; the visual transform is
265
285
  * consumer CSS (headless):
266
286
  * - `[data-active]` — present while at least one drawer is open.
287
+ * - `--drawer-swipe-progress` — 0..1 live dismiss progress of the frontmost drawer.
267
288
  * - `--nested-drawers` — the number of open drawers.
268
289
  * - `--drawer-frontmost-height` — the frontmost drawer's measured size, in pixels.
269
290
  */
@@ -272,7 +293,7 @@ class RdxDrawerIndent {
272
293
  this.provider = inject(RdxDrawerProvider, { optional: true });
273
294
  }
274
295
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerIndent, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
275
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxDrawerIndent, isStandalone: true, selector: "[rdxDrawerIndent]", host: { properties: { "attr.data-active": "provider?.active() ? \"\" : undefined", "style.--nested-drawers": "provider?.count() ?? 0", "style.--drawer-frontmost-height": "(provider?.frontmostHeight() ?? 0) + \"px\"" } }, exportAs: ["rdxDrawerIndent"], ngImport: i0 }); }
296
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxDrawerIndent, isStandalone: true, selector: "[rdxDrawerIndent]", host: { properties: { "attr.data-active": "provider?.active() ? \"\" : undefined", "style.--nested-drawers": "provider?.count() ?? 0", "style.--drawer-frontmost-height": "(provider?.frontmostHeight() ?? 0) + \"px\"", "style.--drawer-swipe-progress": "provider?.swipeProgress() ?? 0" } }, exportAs: ["rdxDrawerIndent"], ngImport: i0 }); }
276
297
  }
277
298
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerIndent, decorators: [{
278
299
  type: Directive,
@@ -282,7 +303,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
282
303
  host: {
283
304
  '[attr.data-active]': 'provider?.active() ? "" : undefined',
284
305
  '[style.--nested-drawers]': 'provider?.count() ?? 0',
285
- '[style.--drawer-frontmost-height]': '(provider?.frontmostHeight() ?? 0) + "px"'
306
+ '[style.--drawer-frontmost-height]': '(provider?.frontmostHeight() ?? 0) + "px"',
307
+ '[style.--drawer-swipe-progress]': 'provider?.swipeProgress() ?? 0'
286
308
  }
287
309
  }]
288
310
  }] });
@@ -290,16 +312,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
290
312
  /**
291
313
  * The page background layer that scales/indents while any drawer is open.
292
314
  *
293
- * Behaves like {@link RdxDrawerIndent} (same `[data-active]` / `--nested-drawers` /
294
- * `--drawer-frontmost-height` contract); kept as a distinct part so the page backdrop and the
295
- * indented content can be styled independently, mirroring Base UI.
315
+ * Behaves like {@link RdxDrawerIndent} (same `[data-active]` / `--drawer-swipe-progress` /
316
+ * `--nested-drawers` / `--drawer-frontmost-height` contract); kept as a distinct part so the page
317
+ * backdrop and the indented content can be styled independently, mirroring Base UI.
296
318
  */
297
319
  class RdxDrawerIndentBackground {
298
320
  constructor() {
299
321
  this.provider = inject(RdxDrawerProvider, { optional: true });
300
322
  }
301
323
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerIndentBackground, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
302
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxDrawerIndentBackground, isStandalone: true, selector: "[rdxDrawerIndentBackground]", host: { properties: { "attr.data-active": "provider?.active() ? \"\" : undefined", "style.--nested-drawers": "provider?.count() ?? 0", "style.--drawer-frontmost-height": "(provider?.frontmostHeight() ?? 0) + \"px\"" } }, exportAs: ["rdxDrawerIndentBackground"], ngImport: i0 }); }
324
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxDrawerIndentBackground, isStandalone: true, selector: "[rdxDrawerIndentBackground]", host: { properties: { "attr.data-active": "provider?.active() ? \"\" : undefined", "style.--nested-drawers": "provider?.count() ?? 0", "style.--drawer-frontmost-height": "(provider?.frontmostHeight() ?? 0) + \"px\"", "style.--drawer-swipe-progress": "provider?.swipeProgress() ?? 0" } }, exportAs: ["rdxDrawerIndentBackground"], ngImport: i0 }); }
303
325
  }
304
326
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerIndentBackground, decorators: [{
305
327
  type: Directive,
@@ -309,7 +331,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
309
331
  host: {
310
332
  '[attr.data-active]': 'provider?.active() ? "" : undefined',
311
333
  '[style.--nested-drawers]': 'provider?.count() ?? 0',
312
- '[style.--drawer-frontmost-height]': '(provider?.frontmostHeight() ?? 0) + "px"'
334
+ '[style.--drawer-frontmost-height]': '(provider?.frontmostHeight() ?? 0) + "px"',
335
+ '[style.--drawer-swipe-progress]': 'provider?.swipeProgress() ?? 0'
313
336
  }
314
337
  }]
315
338
  }] });
@@ -462,7 +485,7 @@ function scrollGuards(target, boundary, direction) {
462
485
  function useDrawerSwipe(config) {
463
486
  assertInInjectionContext(useDrawerSwipe);
464
487
  const element = () => config.element();
465
- const axisSize = () => (isVertical(config.direction()) ? element().offsetHeight : element().offsetWidth);
488
+ const axisSize = () => config.size?.() ?? (isVertical(config.direction()) ? element().offsetHeight : element().offsetWidth);
466
489
  let active = false;
467
490
  let startX = 0;
468
491
  let startY = 0;
@@ -514,7 +537,7 @@ function useDrawerSwipe(config) {
514
537
  if (target?.closest('[data-base-ui-swipe-ignore]')) {
515
538
  return false;
516
539
  }
517
- return !scrollGuards(target, element(), config.direction());
540
+ return !scrollGuards(target, config.boundary?.() ?? element(), config.direction());
518
541
  },
519
542
  onStart: (event) => {
520
543
  active = true;
@@ -574,8 +597,8 @@ function useDrawerSwipe(config) {
574
597
  }
575
598
  if (enabled) {
576
599
  writeMovement(offset, 0);
600
+ config.onProgress?.(0);
577
601
  }
578
- config.onProgress?.(0);
579
602
  });
580
603
  inject(DestroyRef).onDestroy(cancelRaf);
581
604
  }
@@ -633,8 +656,10 @@ class RdxDrawerPopup {
633
656
  }, ...(ngDevMode ? [{ debugName: "frontmostHeightPx" }] : /* istanbul ignore next */ []));
634
657
  useDrawerSwipe({
635
658
  element: () => this.element,
659
+ boundary: () => this.swipeBoundary(),
660
+ size: () => this.visibleAxisSize(),
636
661
  direction: this.drawerContext.swipeDirection,
637
- enabled: computed(() => this.dialogContext.isOpen()),
662
+ enabled: computed(() => this.dialogContext.isOpen() && !this.drawerContext.openingSwipeActive()),
638
663
  restingOffset: this.restingOffset,
639
664
  resolveRelease: (projected, velocity, canDismiss) => this.resolveRelease(projected, velocity, canDismiss),
640
665
  onDismiss: (event) => this.dialogContext.close('swipe', event),
@@ -651,14 +676,55 @@ class RdxDrawerPopup {
651
676
  this.element.style.setProperty('--drawer-snap-point-offset', `${offset}px`);
652
677
  this.drawerContext.reportPopupHeight(size);
653
678
  });
679
+ effect(() => {
680
+ const active = this.drawerContext.openingSwipeActive();
681
+ const distance = this.drawerContext.openingSwipeDistance();
682
+ if (!active) {
683
+ if (distance === Number.POSITIVE_INFINITY) {
684
+ this.element.style.setProperty('--drawer-swipe-movement-x', '0px');
685
+ this.element.style.setProperty('--drawer-swipe-movement-y', '0px');
686
+ this.element.style.setProperty('--drawer-swipe-strength', '0');
687
+ this.drawerContext.setSwipeProgress(0);
688
+ }
689
+ this.element.removeAttribute('data-swiping');
690
+ return;
691
+ }
692
+ const size = this.axisSize() || this.axisElementSize();
693
+ const movement = Math.max(0, size - distance);
694
+ const strength = size > 0 ? movement / size : 1;
695
+ const unit = dismissUnitVector(this.drawerContext.swipeDirection());
696
+ this.element.setAttribute('data-swiping', '');
697
+ this.element.style.setProperty('--drawer-swipe-movement-x', `${unit.x * movement}px`);
698
+ this.element.style.setProperty('--drawer-swipe-movement-y', `${unit.y * movement}px`);
699
+ this.element.style.setProperty('--drawer-swipe-strength', `${strength}`);
700
+ this.drawerContext.setSwipeProgress(strength);
701
+ });
654
702
  }
655
703
  axisSize() {
656
704
  const direction = this.drawerContext.swipeDirection();
657
705
  const size = this.size();
658
- return direction === 'up' || direction === 'down' ? size.height : size.width;
706
+ const measured = direction === 'up' || direction === 'down' ? size.height : size.width;
707
+ return measured || this.axisElementSize();
708
+ }
709
+ axisElementSize() {
710
+ const direction = this.drawerContext.swipeDirection();
711
+ return direction === 'up' || direction === 'down' ? this.element.offsetHeight : this.element.offsetWidth;
712
+ }
713
+ swipeBoundary() {
714
+ return this.element.closest('[rdxDrawerViewport]') ?? this.element;
715
+ }
716
+ visibleAxisSize() {
717
+ const popupSize = this.axisSize();
718
+ const boundary = this.swipeBoundary();
719
+ if (boundary === this.element) {
720
+ return popupSize;
721
+ }
722
+ const direction = this.drawerContext.swipeDirection();
723
+ const boundarySize = direction === 'up' || direction === 'down' ? boundary.clientHeight : boundary.clientWidth;
724
+ return boundarySize > 0 ? Math.min(popupSize, boundarySize) : popupSize;
659
725
  }
660
726
  resolveRelease(projected, velocity, canDismiss) {
661
- const size = this.axisSize();
727
+ const size = this.drawerContext.hasSnapPoints() ? this.axisSize() : this.visibleAxisSize();
662
728
  const dismissAllowed = canDismiss && !this.dialogContext.disablePointerDismissal();
663
729
  if (!this.drawerContext.hasSnapPoints()) {
664
730
  const strength = projected / (size || 1);
@@ -720,99 +786,119 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
720
786
  }], ctorParameters: () => [] });
721
787
 
722
788
  /**
723
- * Moves the drawer to a different part of the DOM. Defaults to `document.body`.
789
+ * Structural directive that teleports the drawer content (backdrop + popup) into a container (default
790
+ * `document.body`) while the drawer is open, keeping it mounted until its CSS exit `@keyframes`
791
+ * finish. It composes the structural {@link RdxDialogPortal}, inheriting the dialog presence context.
792
+ *
793
+ * Use the explicit `<ng-template rdxDrawerPortal>` form; pass `[container]` for a custom target.
724
794
  */
725
795
  class RdxDrawerPortal {
726
796
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerPortal, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
727
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxDrawerPortal, isStandalone: true, selector: "[rdxDrawerPortal]", exportAs: ["rdxDrawerPortal"], hostDirectives: [{ directive: i1.RdxDialogPortal, inputs: ["container", "container"] }], ngImport: i0 }); }
797
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxDrawerPortal, isStandalone: true, selector: "ng-template[rdxDrawerPortal]", exportAs: ["rdxDrawerPortal"], hostDirectives: [{ directive: i1.RdxDialogPortal, inputs: ["container", "container"] }], ngImport: i0 }); }
728
798
  }
729
799
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerPortal, decorators: [{
730
800
  type: Directive,
731
801
  args: [{
732
- selector: '[rdxDrawerPortal]',
802
+ selector: 'ng-template[rdxDrawerPortal]',
733
803
  exportAs: 'rdxDrawerPortal',
734
- hostDirectives: [
735
- {
736
- directive: RdxDialogPortal,
737
- inputs: ['container']
738
- }
739
- ]
804
+ hostDirectives: [{ directive: RdxDialogPortal, inputs: ['container'] }]
740
805
  }]
741
806
  }] });
742
-
743
807
  /**
744
- * Mounts the portal while the drawer is open and waits for CSS exit keyframes before unmounting.
808
+ * Dev-mode guard: `rdxDrawerPortal` is now structural, so the old `<div rdxDrawerPortal>` markup would
809
+ * silently stop portaling — fail loudly instead.
745
810
  */
746
- class RdxDrawerPortalPresence {
747
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerPortalPresence, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
748
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxDrawerPortalPresence, isStandalone: true, selector: "ng-template[rdxDrawerPortalPresence]", hostDirectives: [{ directive: i1.RdxDialogPortalPresence }], ngImport: i0 }); }
811
+ class RdxDrawerPortalMisuseGuard {
812
+ constructor() {
813
+ if (isDevMode()) {
814
+ rdxDevError('drawer/portal-on-element', '`rdxDrawerPortal` is now a structural directive. ' +
815
+ 'Use `<ng-template rdxDrawerPortal>` around the backdrop and popup. ' +
816
+ 'rdxDrawerPortalPresence has been removed.', 'components/drawer');
817
+ }
818
+ }
819
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerPortalMisuseGuard, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
820
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxDrawerPortalMisuseGuard, isStandalone: true, selector: "[rdxDrawerPortal]:not(ng-template)", ngImport: i0 }); }
749
821
  }
750
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerPortalPresence, decorators: [{
822
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerPortalMisuseGuard, decorators: [{
751
823
  type: Directive,
752
824
  args: [{
753
- selector: 'ng-template[rdxDrawerPortalPresence]',
754
- hostDirectives: [RdxDialogPortalPresence]
825
+ selector: '[rdxDrawerPortal]:not(ng-template)'
755
826
  }]
756
- }] });
827
+ }], ctorParameters: () => [] });
757
828
 
758
- /** Pointer travel (px) inward past which the swipe area opens the drawer. */
829
+ /** Pointer travel (px) inward past which releasing the swipe keeps the drawer open. */
759
830
  const OPEN_THRESHOLD = 30;
760
- /** Inward pointer travel (toward the open drawer) for a given direction and pointer delta. */
761
- function inwardDistance(direction, dx, dy) {
831
+ /** Pointer travel in a given direction. */
832
+ function directionalDistance(direction, dx, dy) {
762
833
  switch (direction) {
763
834
  case 'down':
764
- return -dy;
765
- case 'up':
766
835
  return dy;
836
+ case 'up':
837
+ return -dy;
767
838
  case 'left':
768
- return dx;
769
- case 'right':
770
839
  return -dx;
840
+ case 'right':
841
+ return dx;
771
842
  }
772
843
  }
844
+ const oppositeDirection = {
845
+ up: 'down',
846
+ down: 'up',
847
+ left: 'right',
848
+ right: 'left'
849
+ };
850
+ const touchAction = (direction) => direction === 'left' || direction === 'right' ? 'pan-y' : 'pan-x';
773
851
  /**
774
852
  * An off-canvas region (typically pinned to a screen edge) that opens the drawer when swiped inward.
775
853
  *
776
- * Phase 1 opens on a threshold crossing rather than following the pointer live (the popup is not
777
- * mounted while closed); the live-follow open will land with snap points. Shares the drawer's
778
- * pointer-drag lifecycle so capture/cancel handling stays consistent with the popup gesture.
854
+ * Opens the drawer at the start of a drag so its popup can follow the pointer live. Releasing past
855
+ * the threshold settles open; releasing before it or cancelling animates the drawer back out.
779
856
  */
780
857
  class RdxDrawerSwipeArea {
781
858
  constructor() {
782
859
  this.drawerContext = injectRdxDrawerRootContext();
783
860
  this.dialogContext = injectRdxDialogRootContext();
784
- /** Direction the swipe area opens from; defaults to the root's `swipeDirection`. */
861
+ /** Direction the opening gesture travels; defaults to the opposite of the root's dismiss direction. */
785
862
  this.swipeDirection = input(...(ngDevMode ? [undefined, { debugName: "swipeDirection" }] : /* istanbul ignore next */ []));
786
863
  /** Whether the swipe area should ignore user interaction. */
787
864
  this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
788
865
  this.isOpen = computed(() => this.dialogContext.isOpen(), ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
789
- this.direction = computed(() => this.swipeDirection() ?? this.drawerContext.swipeDirection(), ...(ngDevMode ? [{ debugName: "direction" }] : /* istanbul ignore next */ []));
866
+ this.direction = computed(() => this.swipeDirection() ?? oppositeDirection[this.drawerContext.swipeDirection()], ...(ngDevMode ? [{ debugName: "direction" }] : /* istanbul ignore next */ []));
867
+ this.resolvedTouchAction = computed(() => touchAction(this.direction()), ...(ngDevMode ? [{ debugName: "resolvedTouchAction" }] : /* istanbul ignore next */ []));
790
868
  this.swiping = signal(false, ...(ngDevMode ? [{ debugName: "swiping" }] : /* istanbul ignore next */ []));
791
869
  this.startX = 0;
792
870
  this.startY = 0;
871
+ this.distance = 0;
793
872
  usePointerDrag({
794
873
  canStart: () => !this.disabled() && !this.isOpen(),
795
874
  onStart: (event) => {
796
875
  this.startX = event.clientX;
797
876
  this.startY = event.clientY;
877
+ this.distance = 0;
798
878
  this.swiping.set(true);
879
+ this.drawerContext.setOpeningSwipe(true, 0);
880
+ this.dialogContext.open(undefined, undefined, undefined, 'swipe', event);
799
881
  },
800
882
  onMove: (event) => {
801
883
  if (this.disabled()) {
802
884
  return false;
803
885
  }
804
- const distance = inwardDistance(this.direction(), event.clientX - this.startX, event.clientY - this.startY);
805
- if (distance >= OPEN_THRESHOLD) {
806
- this.dialogContext.open(undefined, undefined, undefined, 'swipe', event);
807
- return false;
808
- }
886
+ this.distance = Math.max(0, directionalDistance(this.direction(), event.clientX - this.startX, event.clientY - this.startY));
887
+ this.drawerContext.setOpeningSwipe(true, this.distance);
809
888
  return true;
810
889
  },
811
- onEnd: () => this.swiping.set(false)
890
+ onEnd: (event, committed) => {
891
+ const keepOpen = committed && this.distance >= OPEN_THRESHOLD;
892
+ this.drawerContext.setOpeningSwipe(false, keepOpen ? Number.POSITIVE_INFINITY : this.distance);
893
+ if (!keepOpen) {
894
+ this.dialogContext.close('swipe', event);
895
+ }
896
+ this.swiping.set(false);
897
+ }
812
898
  });
813
899
  }
814
900
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerSwipeArea, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
815
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxDrawerSwipeArea, isStandalone: true, selector: "[rdxDrawerSwipeArea]", inputs: { swipeDirection: { classPropertyName: "swipeDirection", publicName: "swipeDirection", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-open": "isOpen() ? \"\" : undefined", "attr.data-closed": "isOpen() ? undefined : \"\"", "attr.data-disabled": "disabled() ? \"\" : undefined", "attr.data-swiping": "swiping() ? \"\" : undefined", "attr.data-swipe-direction": "direction()" } }, exportAs: ["rdxDrawerSwipeArea"], ngImport: i0 }); }
901
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxDrawerSwipeArea, isStandalone: true, selector: "[rdxDrawerSwipeArea]", inputs: { swipeDirection: { classPropertyName: "swipeDirection", publicName: "swipeDirection", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "presentation", "aria-hidden": "true" }, properties: { "attr.data-open": "isOpen() ? \"\" : undefined", "attr.data-closed": "isOpen() ? undefined : \"\"", "attr.data-disabled": "disabled() ? \"\" : undefined", "attr.data-swiping": "swiping() ? \"\" : undefined", "attr.data-swipe-direction": "direction()", "style.pointer-events": "disabled() || isOpen() ? \"none\" : undefined", "style.touch-action": "resolvedTouchAction()" } }, exportAs: ["rdxDrawerSwipeArea"], ngImport: i0 }); }
816
902
  }
817
903
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerSwipeArea, decorators: [{
818
904
  type: Directive,
@@ -824,7 +910,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
824
910
  '[attr.data-closed]': 'isOpen() ? undefined : ""',
825
911
  '[attr.data-disabled]': 'disabled() ? "" : undefined',
826
912
  '[attr.data-swiping]': 'swiping() ? "" : undefined',
827
- '[attr.data-swipe-direction]': 'direction()'
913
+ '[attr.data-swipe-direction]': 'direction()',
914
+ '[style.pointer-events]': 'disabled() || isOpen() ? "none" : undefined',
915
+ '[style.touch-action]': 'resolvedTouchAction()',
916
+ role: 'presentation',
917
+ 'aria-hidden': 'true'
828
918
  }
829
919
  }]
830
920
  }], ctorParameters: () => [], propDecorators: { swipeDirection: [{ type: i0.Input, args: [{ isSignal: true, alias: "swipeDirection", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
@@ -899,8 +989,8 @@ const drawerImports = [
899
989
  RdxDrawerRoot,
900
990
  RdxDrawerTrigger,
901
991
  RdxDrawerSwipeArea,
902
- RdxDrawerPortalPresence,
903
992
  RdxDrawerPortal,
993
+ RdxDrawerPortalMisuseGuard,
904
994
  RdxDrawerBackdrop,
905
995
  RdxDrawerViewport,
906
996
  RdxDrawerPopup,
@@ -917,8 +1007,8 @@ class RdxDrawerModule {
917
1007
  RdxDrawerRoot,
918
1008
  RdxDrawerTrigger,
919
1009
  RdxDrawerSwipeArea,
920
- RdxDrawerPortalPresence,
921
1010
  RdxDrawerPortal,
1011
+ RdxDrawerPortalMisuseGuard,
922
1012
  RdxDrawerBackdrop,
923
1013
  RdxDrawerViewport,
924
1014
  RdxDrawerPopup,
@@ -931,8 +1021,8 @@ class RdxDrawerModule {
931
1021
  RdxDrawerRoot,
932
1022
  RdxDrawerTrigger,
933
1023
  RdxDrawerSwipeArea,
934
- RdxDrawerPortalPresence,
935
1024
  RdxDrawerPortal,
1025
+ RdxDrawerPortalMisuseGuard,
936
1026
  RdxDrawerBackdrop,
937
1027
  RdxDrawerViewport,
938
1028
  RdxDrawerPopup,
@@ -956,5 +1046,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
956
1046
  * Generated bundle index. Do not edit.
957
1047
  */
958
1048
 
959
- export { RdxDrawerBackdrop, RdxDrawerClose, RdxDrawerContent, RdxDrawerDescription, RdxDrawerHandle, RdxDrawerIndent, RdxDrawerIndentBackground, RdxDrawerModule, RdxDrawerPopup, RdxDrawerPortal, RdxDrawerPortalPresence, RdxDrawerProvider, RdxDrawerProviderDirective, RdxDrawerRoot, RdxDrawerSwipeArea, RdxDrawerTitle, RdxDrawerTrigger, RdxDrawerViewport, buildSnapEntries, createRdxDrawerHandle, dismissUnitVector, drawerImports, injectRdxDrawerRootContext, provideRdxDrawerProvider, provideRdxDrawerRootContext, resolveSnapTarget, snapPointReveal, useDrawerSwipe };
1049
+ export { RdxDrawerBackdrop, RdxDrawerClose, RdxDrawerContent, RdxDrawerDescription, RdxDrawerHandle, RdxDrawerIndent, RdxDrawerIndentBackground, RdxDrawerModule, RdxDrawerPopup, RdxDrawerPortal, RdxDrawerPortalMisuseGuard, RdxDrawerProvider, RdxDrawerProviderDirective, RdxDrawerRoot, RdxDrawerSwipeArea, RdxDrawerTitle, RdxDrawerTrigger, RdxDrawerViewport, buildSnapEntries, createRdxDrawerHandle, dismissUnitVector, drawerImports, injectRdxDrawerRootContext, provideRdxDrawerProvider, provideRdxDrawerRootContext, resolveSnapTarget, snapPointReveal, useDrawerSwipe };
960
1050
  //# sourceMappingURL=radix-ng-primitives-drawer.mjs.map