@radix-ng/primitives 0.50.0 → 1.0.0-beta.0

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 (207) hide show
  1. package/collection/README.md +1 -0
  2. package/fesm2022/radix-ng-primitives-accordion.mjs +134 -66
  3. package/fesm2022/radix-ng-primitives-accordion.mjs.map +1 -1
  4. package/fesm2022/radix-ng-primitives-alert-dialog.mjs +224 -132
  5. package/fesm2022/radix-ng-primitives-alert-dialog.mjs.map +1 -1
  6. package/fesm2022/radix-ng-primitives-arrow.mjs +26 -10
  7. package/fesm2022/radix-ng-primitives-arrow.mjs.map +1 -1
  8. package/fesm2022/radix-ng-primitives-aspect-ratio.mjs +6 -6
  9. package/fesm2022/radix-ng-primitives-aspect-ratio.mjs.map +1 -1
  10. package/fesm2022/radix-ng-primitives-avatar.mjs +68 -75
  11. package/fesm2022/radix-ng-primitives-avatar.mjs.map +1 -1
  12. package/fesm2022/radix-ng-primitives-button.mjs +123 -0
  13. package/fesm2022/radix-ng-primitives-button.mjs.map +1 -0
  14. package/fesm2022/radix-ng-primitives-calendar.mjs +104 -103
  15. package/fesm2022/radix-ng-primitives-calendar.mjs.map +1 -1
  16. package/fesm2022/radix-ng-primitives-checkbox.mjs +414 -80
  17. package/fesm2022/radix-ng-primitives-checkbox.mjs.map +1 -1
  18. package/fesm2022/radix-ng-primitives-collapsible.mjs +193 -92
  19. package/fesm2022/radix-ng-primitives-collapsible.mjs.map +1 -1
  20. package/fesm2022/radix-ng-primitives-collection.mjs +72 -0
  21. package/fesm2022/radix-ng-primitives-collection.mjs.map +1 -0
  22. package/fesm2022/radix-ng-primitives-config.mjs +5 -5
  23. package/fesm2022/radix-ng-primitives-config.mjs.map +1 -1
  24. package/fesm2022/radix-ng-primitives-context-menu.mjs +143 -427
  25. package/fesm2022/radix-ng-primitives-context-menu.mjs.map +1 -1
  26. package/fesm2022/radix-ng-primitives-core.mjs +757 -757
  27. package/fesm2022/radix-ng-primitives-core.mjs.map +1 -1
  28. package/fesm2022/radix-ng-primitives-cropper.mjs +55 -53
  29. package/fesm2022/radix-ng-primitives-cropper.mjs.map +1 -1
  30. package/fesm2022/radix-ng-primitives-date-field.mjs +93 -86
  31. package/fesm2022/radix-ng-primitives-date-field.mjs.map +1 -1
  32. package/fesm2022/radix-ng-primitives-dialog.mjs +658 -330
  33. package/fesm2022/radix-ng-primitives-dialog.mjs.map +1 -1
  34. package/fesm2022/radix-ng-primitives-dismissable-layer.mjs +98 -76
  35. package/fesm2022/radix-ng-primitives-dismissable-layer.mjs.map +1 -1
  36. package/fesm2022/radix-ng-primitives-drawer.mjs +1059 -0
  37. package/fesm2022/radix-ng-primitives-drawer.mjs.map +1 -0
  38. package/fesm2022/radix-ng-primitives-editable.mjs +20 -20
  39. package/fesm2022/radix-ng-primitives-editable.mjs.map +1 -1
  40. package/fesm2022/radix-ng-primitives-field.mjs +363 -0
  41. package/fesm2022/radix-ng-primitives-field.mjs.map +1 -0
  42. package/fesm2022/radix-ng-primitives-fieldset.mjs +79 -0
  43. package/fesm2022/radix-ng-primitives-fieldset.mjs.map +1 -0
  44. package/fesm2022/radix-ng-primitives-focus-guards.mjs +3 -3
  45. package/fesm2022/radix-ng-primitives-focus-guards.mjs.map +1 -1
  46. package/fesm2022/radix-ng-primitives-focus-scope.mjs +29 -14
  47. package/fesm2022/radix-ng-primitives-focus-scope.mjs.map +1 -1
  48. package/fesm2022/radix-ng-primitives-input.mjs +172 -0
  49. package/fesm2022/radix-ng-primitives-input.mjs.map +1 -0
  50. package/fesm2022/radix-ng-primitives-label.mjs +11 -11
  51. package/fesm2022/radix-ng-primitives-label.mjs.map +1 -1
  52. package/fesm2022/radix-ng-primitives-menu.mjs +1484 -353
  53. package/fesm2022/radix-ng-primitives-menu.mjs.map +1 -1
  54. package/fesm2022/radix-ng-primitives-menubar.mjs +290 -162
  55. package/fesm2022/radix-ng-primitives-menubar.mjs.map +1 -1
  56. package/fesm2022/radix-ng-primitives-meter.mjs +271 -0
  57. package/fesm2022/radix-ng-primitives-meter.mjs.map +1 -0
  58. package/fesm2022/radix-ng-primitives-navigation-menu.mjs +1060 -1553
  59. package/fesm2022/radix-ng-primitives-navigation-menu.mjs.map +1 -1
  60. package/fesm2022/radix-ng-primitives-number-field.mjs +1102 -366
  61. package/fesm2022/radix-ng-primitives-number-field.mjs.map +1 -1
  62. package/fesm2022/radix-ng-primitives-pagination.mjs +51 -51
  63. package/fesm2022/radix-ng-primitives-pagination.mjs.map +1 -1
  64. package/fesm2022/radix-ng-primitives-popover.mjs +980 -995
  65. package/fesm2022/radix-ng-primitives-popover.mjs.map +1 -1
  66. package/fesm2022/radix-ng-primitives-popper.mjs +137 -82
  67. package/fesm2022/radix-ng-primitives-popper.mjs.map +1 -1
  68. package/fesm2022/radix-ng-primitives-portal.mjs +40 -16
  69. package/fesm2022/radix-ng-primitives-portal.mjs.map +1 -1
  70. package/fesm2022/radix-ng-primitives-presence.mjs +134 -246
  71. package/fesm2022/radix-ng-primitives-presence.mjs.map +1 -1
  72. package/fesm2022/radix-ng-primitives-preview-card.mjs +997 -0
  73. package/fesm2022/radix-ng-primitives-preview-card.mjs.map +1 -0
  74. package/fesm2022/radix-ng-primitives-progress.mjs +231 -92
  75. package/fesm2022/radix-ng-primitives-progress.mjs.map +1 -1
  76. package/fesm2022/radix-ng-primitives-radio.mjs +211 -70
  77. package/fesm2022/radix-ng-primitives-radio.mjs.map +1 -1
  78. package/fesm2022/radix-ng-primitives-roving-focus.mjs +127 -77
  79. package/fesm2022/radix-ng-primitives-roving-focus.mjs.map +1 -1
  80. package/fesm2022/radix-ng-primitives-select.mjs +791 -511
  81. package/fesm2022/radix-ng-primitives-select.mjs.map +1 -1
  82. package/fesm2022/radix-ng-primitives-separator.mjs +16 -45
  83. package/fesm2022/radix-ng-primitives-separator.mjs.map +1 -1
  84. package/fesm2022/radix-ng-primitives-slider.mjs +976 -720
  85. package/fesm2022/radix-ng-primitives-slider.mjs.map +1 -1
  86. package/fesm2022/radix-ng-primitives-stepper.mjs +69 -71
  87. package/fesm2022/radix-ng-primitives-stepper.mjs.map +1 -1
  88. package/fesm2022/radix-ng-primitives-switch.mjs +128 -124
  89. package/fesm2022/radix-ng-primitives-switch.mjs.map +1 -1
  90. package/fesm2022/radix-ng-primitives-tabs.mjs +388 -115
  91. package/fesm2022/radix-ng-primitives-tabs.mjs.map +1 -1
  92. package/fesm2022/radix-ng-primitives-time-field.mjs +111 -117
  93. package/fesm2022/radix-ng-primitives-time-field.mjs.map +1 -1
  94. package/fesm2022/radix-ng-primitives-toggle-group.mjs +122 -248
  95. package/fesm2022/radix-ng-primitives-toggle-group.mjs.map +1 -1
  96. package/fesm2022/radix-ng-primitives-toggle.mjs +99 -62
  97. package/fesm2022/radix-ng-primitives-toggle.mjs.map +1 -1
  98. package/fesm2022/radix-ng-primitives-toolbar.mjs +307 -94
  99. package/fesm2022/radix-ng-primitives-toolbar.mjs.map +1 -1
  100. package/fesm2022/radix-ng-primitives-tooltip.mjs +690 -1079
  101. package/fesm2022/radix-ng-primitives-tooltip.mjs.map +1 -1
  102. package/fesm2022/radix-ng-primitives-visually-hidden.mjs +46 -87
  103. package/fesm2022/radix-ng-primitives-visually-hidden.mjs.map +1 -1
  104. package/fesm2022/radix-ng-primitives.mjs.map +1 -1
  105. package/meter/README.md +3 -0
  106. package/navigation-menu/README.md +2 -1
  107. package/package.json +85 -63
  108. package/portal/README.md +2 -0
  109. package/preview-card/README.md +3 -0
  110. package/schematics/collection.json +1 -0
  111. package/schematics/ng-add/index.d.ts +3 -2
  112. package/schematics/ng-add/index.js +62 -31
  113. package/schematics/ng-add/index.js.map +1 -1
  114. package/schematics/ng-add/package-config.d.ts +4 -2
  115. package/schematics/ng-add/package-config.js +10 -2
  116. package/schematics/ng-add/package-config.js.map +1 -1
  117. package/schematics/ng-add/schema.d.ts +3 -0
  118. package/schematics/ng-add/schema.js +3 -0
  119. package/schematics/ng-add/schema.js.map +1 -0
  120. package/schematics/ng-add/schema.json +14 -0
  121. package/select/README.md +2 -0
  122. package/{accordion/index.d.ts → types/radix-ng-primitives-accordion.d.ts} +102 -67
  123. package/types/radix-ng-primitives-alert-dialog.d.ts +114 -0
  124. package/{arrow/index.d.ts → types/radix-ng-primitives-arrow.d.ts} +1 -1
  125. package/{aspect-ratio/index.d.ts → types/radix-ng-primitives-aspect-ratio.d.ts} +1 -1
  126. package/{avatar/index.d.ts → types/radix-ng-primitives-avatar.d.ts} +7 -11
  127. package/types/radix-ng-primitives-button.d.ts +73 -0
  128. package/{calendar/index.d.ts → types/radix-ng-primitives-calendar.d.ts} +2 -3
  129. package/types/radix-ng-primitives-checkbox.d.ts +337 -0
  130. package/types/radix-ng-primitives-collapsible.d.ts +159 -0
  131. package/types/radix-ng-primitives-collection.d.ts +44 -0
  132. package/{config/index.d.ts → types/radix-ng-primitives-config.d.ts} +1 -1
  133. package/types/radix-ng-primitives-context-menu.d.ts +73 -0
  134. package/{core/index.d.ts → types/radix-ng-primitives-core.d.ts} +311 -236
  135. package/{cropper/index.d.ts → types/radix-ng-primitives-cropper.d.ts} +6 -5
  136. package/{date-field/index.d.ts → types/radix-ng-primitives-date-field.d.ts} +42 -27
  137. package/types/radix-ng-primitives-dialog.d.ts +323 -0
  138. package/{dismissable-layer/index.d.ts → types/radix-ng-primitives-dismissable-layer.d.ts} +15 -7
  139. package/types/radix-ng-primitives-drawer.d.ts +448 -0
  140. package/{editable/index.d.ts → types/radix-ng-primitives-editable.d.ts} +1 -1
  141. package/types/radix-ng-primitives-field.d.ts +373 -0
  142. package/types/radix-ng-primitives-fieldset.d.ts +48 -0
  143. package/{focus-scope/index.d.ts → types/radix-ng-primitives-focus-scope.d.ts} +13 -5
  144. package/types/radix-ng-primitives-input.d.ts +87 -0
  145. package/{label/index.d.ts → types/radix-ng-primitives-label.d.ts} +0 -1
  146. package/types/radix-ng-primitives-menu.d.ts +612 -0
  147. package/types/radix-ng-primitives-menubar.d.ts +66 -0
  148. package/types/radix-ng-primitives-meter.d.ts +193 -0
  149. package/types/radix-ng-primitives-navigation-menu.d.ts +488 -0
  150. package/types/radix-ng-primitives-number-field.d.ts +464 -0
  151. package/{pagination/index.d.ts → types/radix-ng-primitives-pagination.d.ts} +2 -2
  152. package/types/radix-ng-primitives-popover.d.ts +416 -0
  153. package/{popper/index.d.ts → types/radix-ng-primitives-popper.d.ts} +50 -9
  154. package/types/radix-ng-primitives-portal.d.ts +30 -0
  155. package/types/radix-ng-primitives-presence.d.ts +55 -0
  156. package/types/radix-ng-primitives-preview-card.d.ts +359 -0
  157. package/types/radix-ng-primitives-progress.d.ts +206 -0
  158. package/{radio/index.d.ts → types/radix-ng-primitives-radio.d.ts} +56 -26
  159. package/{roving-focus/index.d.ts → types/radix-ng-primitives-roving-focus.d.ts} +38 -27
  160. package/types/radix-ng-primitives-select.d.ts +512 -0
  161. package/types/radix-ng-primitives-separator.d.ts +38 -0
  162. package/types/radix-ng-primitives-slider.d.ts +377 -0
  163. package/{stepper/index.d.ts → types/radix-ng-primitives-stepper.d.ts} +21 -22
  164. package/types/radix-ng-primitives-switch.d.ts +121 -0
  165. package/types/radix-ng-primitives-tabs.d.ts +247 -0
  166. package/{time-field/index.d.ts → types/radix-ng-primitives-time-field.d.ts} +46 -31
  167. package/types/radix-ng-primitives-toggle-group.d.ts +116 -0
  168. package/types/radix-ng-primitives-toggle.d.ts +65 -0
  169. package/types/radix-ng-primitives-toolbar.d.ts +180 -0
  170. package/types/radix-ng-primitives-tooltip.d.ts +395 -0
  171. package/{visually-hidden/index.d.ts → types/radix-ng-primitives-visually-hidden.d.ts} +19 -19
  172. package/alert-dialog/index.d.ts +0 -57
  173. package/checkbox/index.d.ts +0 -164
  174. package/collapsible/index.d.ts +0 -85
  175. package/context-menu/index.d.ts +0 -129
  176. package/dialog/index.d.ts +0 -205
  177. package/dropdown-menu/README.md +0 -1
  178. package/dropdown-menu/index.d.ts +0 -171
  179. package/fesm2022/radix-ng-primitives-dropdown-menu.mjs +0 -583
  180. package/fesm2022/radix-ng-primitives-dropdown-menu.mjs.map +0 -1
  181. package/fesm2022/radix-ng-primitives-hover-card.mjs +0 -1246
  182. package/fesm2022/radix-ng-primitives-hover-card.mjs.map +0 -1
  183. package/fesm2022/radix-ng-primitives-tooltip2.mjs +0 -740
  184. package/fesm2022/radix-ng-primitives-tooltip2.mjs.map +0 -1
  185. package/hover-card/README.md +0 -3
  186. package/hover-card/index.d.ts +0 -472
  187. package/menu/index.d.ts +0 -139
  188. package/menubar/index.d.ts +0 -56
  189. package/navigation-menu/index.d.ts +0 -405
  190. package/number-field/index.d.ts +0 -203
  191. package/popover/index.d.ts +0 -403
  192. package/portal/index.d.ts +0 -22
  193. package/presence/index.d.ts +0 -103
  194. package/progress/index.d.ts +0 -79
  195. package/select/index.d.ts +0 -214
  196. package/separator/index.d.ts +0 -63
  197. package/slider/index.d.ts +0 -263
  198. package/switch/index.d.ts +0 -105
  199. package/tabs/index.d.ts +0 -112
  200. package/toggle/index.d.ts +0 -75
  201. package/toggle-group/index.d.ts +0 -194
  202. package/toolbar/index.d.ts +0 -55
  203. package/tooltip/index.d.ts +0 -433
  204. package/tooltip2/README.md +0 -3
  205. package/tooltip2/index.d.ts +0 -325
  206. /package/{focus-guards/index.d.ts → types/radix-ng-primitives-focus-guards.d.ts} +0 -0
  207. /package/{index.d.ts → types/radix-ng-primitives.d.ts} +0 -0
@@ -0,0 +1,1059 @@
1
+ import * as i0 from '@angular/core';
2
+ import { signal, computed, Injectable, Directive, inject, input, model, booleanAttribute, output, effect, untracked, assertInInjectionContext, PLATFORM_ID, ElementRef, DestroyRef, Injector, NgModule } from '@angular/core';
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, elementSize } from '@radix-ng/primitives/core';
6
+ import { isPlatformBrowser } from '@angular/common';
7
+
8
+ /**
9
+ * App-level coordinator that tracks every open drawer so background content can react to them
10
+ * (the page-scale / indent effect). Provide it once near the app root with
11
+ * {@link provideRdxDrawerProvider} or the `[rdxDrawerProvider]` directive; drawers that find it in
12
+ * their injector register while open. It is optional — drawers work without it.
13
+ */
14
+ class RdxDrawerProvider {
15
+ constructor() {
16
+ this.stack = signal([], ...(ngDevMode ? [{ debugName: "stack" }] : /* istanbul ignore next */ []));
17
+ /** Number of open drawers. */
18
+ this.count = computed(() => this.stack().length, ...(ngDevMode ? [{ debugName: "count" }] : /* istanbul ignore next */ []));
19
+ /** Whether any drawer is open. */
20
+ this.active = computed(() => this.count() > 0, ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
21
+ /** The most recently opened (frontmost) drawer, or `null`. */
22
+ this.frontmost = computed(() => this.stack().at(-1) ?? null, ...(ngDevMode ? [{ debugName: "frontmost" }] : /* istanbul ignore next */ []));
23
+ /** The frontmost drawer's measured size (px), or `0` when none is open. */
24
+ this.frontmostHeight = computed(() => this.frontmost()?.height() ?? 0, ...(ngDevMode ? [{ debugName: "frontmostHeight" }] : /* istanbul ignore next */ []));
25
+ }
26
+ /** Register an open drawer; returns a disposer that removes it. */
27
+ register(registration) {
28
+ this.stack.update((stack) => [...stack, registration]);
29
+ return () => this.stack.update((stack) => stack.filter((entry) => entry !== registration));
30
+ }
31
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
32
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerProvider }); }
33
+ }
34
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerProvider, decorators: [{
35
+ type: Injectable
36
+ }] });
37
+ /** Provide a {@link RdxDrawerProvider} for an app (e.g. in `app.config.ts`). */
38
+ function provideRdxDrawerProvider() {
39
+ return [RdxDrawerProvider];
40
+ }
41
+ /**
42
+ * Hosts a {@link RdxDrawerProvider} for its subtree. Put it on a wrapping element so descendant
43
+ * drawer roots and `rdxDrawerIndent*` parts share one coordinator.
44
+ */
45
+ class RdxDrawerProviderDirective {
46
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerProviderDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
47
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxDrawerProviderDirective, isStandalone: true, selector: "[rdxDrawerProvider]", providers: [RdxDrawerProvider], exportAs: ["rdxDrawerProvider"], ngImport: i0 }); }
48
+ }
49
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerProviderDirective, decorators: [{
50
+ type: Directive,
51
+ args: [{
52
+ selector: '[rdxDrawerProvider]',
53
+ exportAs: 'rdxDrawerProvider',
54
+ providers: [RdxDrawerProvider]
55
+ }]
56
+ }] });
57
+
58
+ const [injectRdxDrawerRootContext, provideRdxDrawerRootContext] = createContext('RdxDrawerRootContext');
59
+ const context = () => {
60
+ const root = inject(RdxDrawerRoot);
61
+ return {
62
+ swipeDirection: root.swipeDirection,
63
+ swipeProgress: root.swipeProgress.asReadonly(),
64
+ setSwipeProgress: (value) => root.swipeProgress.set(value),
65
+ snapPoints: root.normalizedSnapPoints,
66
+ hasSnapPoints: root.hasSnapPoints,
67
+ activeSnapPoint: root.snapPoint,
68
+ sequentialSnap: root.snapToSequentialPoints,
69
+ setActiveSnapPoint: (value, emit) => root.setActiveSnapPoint(value, emit),
70
+ nestedDrawerOpen: root.nestedDrawerOpen,
71
+ nestedDrawerCount: root.nestedDrawerCount,
72
+ frontmostHeight: root.frontmostHeight,
73
+ reportPopupHeight: (height) => root.popupHeight.set(height)
74
+ };
75
+ };
76
+ /**
77
+ * Groups all parts of the drawer.
78
+ *
79
+ * Composes the Dialog primitive directly (modal-by-default but user-overridable) and layers the
80
+ * drawer-specific swipe and snap-point contract on top via {@link RdxDrawerRootContext}. Modality,
81
+ * dismissal and detached-trigger handling are the dialog's: the `modal`, `disablePointerDismissal`
82
+ * and `handle` inputs are proxied straight through, so a drawer is a modal dialog the user can make
83
+ * non-modal.
84
+ */
85
+ class RdxDrawerRoot {
86
+ constructor() {
87
+ this.dialog = inject(RdxDialogRoot);
88
+ this.provider = inject(RdxDrawerProvider, { optional: true });
89
+ /** The popup's measured size (px) along its dismiss axis, reported by the popup. */
90
+ this.popupHeight = signal(0, ...(ngDevMode ? [{ debugName: "popupHeight" }] : /* istanbul ignore next */ []));
91
+ /**
92
+ * Direction a swipe travels to dismiss the drawer. The visual side of the drawer is consumer
93
+ * CSS; this controls the dismiss gesture and the `data-swipe-direction` styling hook.
94
+ */
95
+ this.swipeDirection = input('down', ...(ngDevMode ? [{ debugName: "swipeDirection" }] : /* istanbul ignore next */ []));
96
+ /**
97
+ * 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.
99
+ */
100
+ this.snapPoints = input(...(ngDevMode ? [undefined, { debugName: "snapPoints" }] : /* istanbul ignore next */ []));
101
+ /** The active snap point (controlled / uncontrolled with `[(snapPoint)]`). */
102
+ 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. */
104
+ this.defaultSnapPoint = input(...(ngDevMode ? [undefined, { debugName: "defaultSnapPoint" }] : /* istanbul ignore next */ []));
105
+ /** Step at most one snap point per release instead of letting velocity skip points. */
106
+ this.snapToSequentialPoints = input(false, { ...(ngDevMode ? { debugName: "snapToSequentialPoints" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
107
+ /** Emits when the active snap point changes through a gesture. */
108
+ this.onSnapPointChange = output();
109
+ /** 0..1 progress of the active dismiss gesture, written by the popup's swipe engine. */
110
+ this.swipeProgress = signal(0, ...(ngDevMode ? [{ debugName: "swipeProgress" }] : /* istanbul ignore next */ []));
111
+ this.normalizedSnapPoints = computed(() => this.snapPoints() ?? [], ...(ngDevMode ? [{ debugName: "normalizedSnapPoints" }] : /* istanbul ignore next */ []));
112
+ this.hasSnapPoints = computed(() => this.normalizedSnapPoints().length > 0, ...(ngDevMode ? [{ debugName: "hasSnapPoints" }] : /* istanbul ignore next */ []));
113
+ /** Whether a drawer nested inside this one is open (reuses the dialog's nesting detection). */
114
+ this.nestedDrawerOpen = this.dialog.nestedDialogOpen;
115
+ /** Number of open drawers nested inside this one. */
116
+ this.nestedDrawerCount = this.dialog.nestedOpenCount.asReadonly();
117
+ /** The app-wide frontmost drawer's measured size (px); `0` without a provider. */
118
+ this.frontmostHeight = computed(() => this.provider?.frontmostHeight() ?? 0, ...(ngDevMode ? [{ debugName: "frontmostHeight" }] : /* istanbul ignore next */ []));
119
+ /** Whether the drawer is open (read-only mirror of the composed dialog state). */
120
+ this.open = this.dialog.open;
121
+ /** The active trigger's id. */
122
+ this.triggerId = this.dialog.triggerId;
123
+ /** Payload of the active trigger. */
124
+ this.payload = this.dialog.payload;
125
+ // Apply the default snap point when opening without one set. The active snap point is left
126
+ // untouched on close: clearing it would clobber a controlled `[(snapPoint)]` binding, and an
127
+ // uncontrolled drawer simply reopens where it was left.
128
+ effect(() => {
129
+ const open = this.dialog.open();
130
+ untracked(() => {
131
+ const points = this.normalizedSnapPoints();
132
+ if (open && this.snapPoint() === null && points.length > 0) {
133
+ this.snapPoint.set(this.defaultSnapPoint() ?? points[points.length - 1]);
134
+ }
135
+ });
136
+ });
137
+ // Reset live swipe progress when closed so a reopened drawer never starts mid-gesture.
138
+ effect(() => {
139
+ if (!this.dialog.open()) {
140
+ untracked(() => this.swipeProgress.set(0));
141
+ }
142
+ });
143
+ // Register with the optional app-level provider while open so background content can react.
144
+ effect((onCleanup) => {
145
+ if (this.dialog.open() && this.provider) {
146
+ onCleanup(untracked(() => this.provider.register({ id: this.dialog.contentId, height: this.popupHeight.asReadonly() })));
147
+ }
148
+ });
149
+ }
150
+ setActiveSnapPoint(value, emit) {
151
+ this.snapPoint.set(value);
152
+ if (emit) {
153
+ this.onSnapPointChange.emit(value);
154
+ }
155
+ }
156
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerRoot, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
157
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxDrawerRoot, isStandalone: true, selector: "[rdxDrawerRoot]", inputs: { swipeDirection: { classPropertyName: "swipeDirection", publicName: "swipeDirection", isSignal: true, isRequired: false, transformFunction: null }, snapPoints: { classPropertyName: "snapPoints", publicName: "snapPoints", isSignal: true, isRequired: false, transformFunction: null }, snapPoint: { classPropertyName: "snapPoint", publicName: "snapPoint", isSignal: true, isRequired: false, transformFunction: null }, defaultSnapPoint: { classPropertyName: "defaultSnapPoint", publicName: "defaultSnapPoint", isSignal: true, isRequired: false, transformFunction: null }, snapToSequentialPoints: { classPropertyName: "snapToSequentialPoints", publicName: "snapToSequentialPoints", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { snapPoint: "snapPointChange", onSnapPointChange: "onSnapPointChange" }, providers: [provideRdxDrawerRootContext(context)], exportAs: ["rdxDrawerRoot"], hostDirectives: [{ directive: i1.RdxDialogRoot, inputs: ["open", "open", "defaultOpen", "defaultOpen", "triggerId", "triggerId", "defaultTriggerId", "defaultTriggerId", "handle", "handle", "modal", "modal", "disablePointerDismissal", "disablePointerDismissal"], outputs: ["openChange", "openChange", "triggerIdChange", "triggerIdChange", "onOpenChange", "onOpenChange", "onOpenChangeComplete", "onOpenChangeComplete"] }], ngImport: i0 }); }
158
+ }
159
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerRoot, decorators: [{
160
+ type: Directive,
161
+ args: [{
162
+ selector: '[rdxDrawerRoot]',
163
+ exportAs: 'rdxDrawerRoot',
164
+ hostDirectives: [
165
+ {
166
+ directive: RdxDialogRoot,
167
+ inputs: [
168
+ 'open',
169
+ 'defaultOpen',
170
+ 'triggerId',
171
+ 'defaultTriggerId',
172
+ 'handle',
173
+ 'modal',
174
+ 'disablePointerDismissal'
175
+ ],
176
+ outputs: ['openChange', 'triggerIdChange', 'onOpenChange', 'onOpenChangeComplete']
177
+ }
178
+ ],
179
+ providers: [provideRdxDrawerRootContext(context)]
180
+ }]
181
+ }], ctorParameters: () => [], propDecorators: { swipeDirection: [{ type: i0.Input, args: [{ isSignal: true, alias: "swipeDirection", required: false }] }], snapPoints: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapPoints", required: false }] }], snapPoint: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapPoint", required: false }] }, { type: i0.Output, args: ["snapPointChange"] }], defaultSnapPoint: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultSnapPoint", required: false }] }], snapToSequentialPoints: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToSequentialPoints", required: false }] }], onSnapPointChange: [{ type: i0.Output, args: ["onSnapPointChange"] }] } });
182
+
183
+ /**
184
+ * An overlay displayed beneath the drawer popup.
185
+ *
186
+ * Composes the dialog backdrop and additionally exposes `--drawer-swipe-progress` (0..1) so the
187
+ * consumer can fade it in step with the dismiss gesture.
188
+ */
189
+ class RdxDrawerBackdrop {
190
+ constructor() {
191
+ this.drawerContext = injectRdxDrawerRootContext();
192
+ }
193
+ 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 }); }
195
+ }
196
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerBackdrop, decorators: [{
197
+ type: Directive,
198
+ args: [{
199
+ selector: '[rdxDrawerBackdrop]',
200
+ exportAs: 'rdxDrawerBackdrop',
201
+ hostDirectives: [RdxDialogBackdrop],
202
+ host: {
203
+ '[style.--drawer-swipe-progress]': 'drawerContext.swipeProgress()',
204
+ '[attr.data-nested-drawer-open]': 'drawerContext.nestedDrawerOpen() ? "" : undefined'
205
+ }
206
+ }]
207
+ }] });
208
+
209
+ /**
210
+ * A button that closes the drawer.
211
+ */
212
+ class RdxDrawerClose {
213
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerClose, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
214
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxDrawerClose, isStandalone: true, selector: "button[rdxDrawerClose]", exportAs: ["rdxDrawerClose"], hostDirectives: [{ directive: i1.RdxDialogClose }], ngImport: i0 }); }
215
+ }
216
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerClose, decorators: [{
217
+ type: Directive,
218
+ args: [{
219
+ selector: 'button[rdxDrawerClose]',
220
+ exportAs: 'rdxDrawerClose',
221
+ hostDirectives: [RdxDialogClose]
222
+ }]
223
+ }] });
224
+
225
+ /**
226
+ * The scrollable body of the drawer.
227
+ *
228
+ * A structural marker so the anatomy matches Base UI. The popup's swipe engine yields to scrolling
229
+ * inside this region automatically (it only starts a dismiss gesture when the scroll is at its
230
+ * edge), so no extra wiring is needed. Opt individual elements out of swiping with the
231
+ * `data-base-ui-swipe-ignore` attribute.
232
+ */
233
+ class RdxDrawerContent {
234
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerContent, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
235
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxDrawerContent, isStandalone: true, selector: "[rdxDrawerContent]", exportAs: ["rdxDrawerContent"], ngImport: i0 }); }
236
+ }
237
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerContent, decorators: [{
238
+ type: Directive,
239
+ args: [{
240
+ selector: '[rdxDrawerContent]',
241
+ exportAs: 'rdxDrawerContent'
242
+ }]
243
+ }] });
244
+
245
+ /**
246
+ * An accessible description announced when the drawer is opened.
247
+ */
248
+ class RdxDrawerDescription {
249
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerDescription, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
250
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxDrawerDescription, isStandalone: true, selector: "[rdxDrawerDescription]", exportAs: ["rdxDrawerDescription"], hostDirectives: [{ directive: i1.RdxDialogDescription }], ngImport: i0 }); }
251
+ }
252
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerDescription, decorators: [{
253
+ type: Directive,
254
+ args: [{
255
+ selector: '[rdxDrawerDescription]',
256
+ exportAs: 'rdxDrawerDescription',
257
+ hostDirectives: [RdxDialogDescription]
258
+ }]
259
+ }] });
260
+
261
+ /**
262
+ * Background content that scales/indents while any drawer is open.
263
+ *
264
+ * Reads the nearest {@link RdxDrawerProvider} and exposes styling hooks; the visual transform is
265
+ * consumer CSS (headless):
266
+ * - `[data-active]` — present while at least one drawer is open.
267
+ * - `--nested-drawers` — the number of open drawers.
268
+ * - `--drawer-frontmost-height` — the frontmost drawer's measured size, in pixels.
269
+ */
270
+ class RdxDrawerIndent {
271
+ constructor() {
272
+ this.provider = inject(RdxDrawerProvider, { optional: true });
273
+ }
274
+ 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 }); }
276
+ }
277
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerIndent, decorators: [{
278
+ type: Directive,
279
+ args: [{
280
+ selector: '[rdxDrawerIndent]',
281
+ exportAs: 'rdxDrawerIndent',
282
+ host: {
283
+ '[attr.data-active]': 'provider?.active() ? "" : undefined',
284
+ '[style.--nested-drawers]': 'provider?.count() ?? 0',
285
+ '[style.--drawer-frontmost-height]': '(provider?.frontmostHeight() ?? 0) + "px"'
286
+ }
287
+ }]
288
+ }] });
289
+
290
+ /**
291
+ * The page background layer that scales/indents while any drawer is open.
292
+ *
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.
296
+ */
297
+ class RdxDrawerIndentBackground {
298
+ constructor() {
299
+ this.provider = inject(RdxDrawerProvider, { optional: true });
300
+ }
301
+ 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 }); }
303
+ }
304
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerIndentBackground, decorators: [{
305
+ type: Directive,
306
+ args: [{
307
+ selector: '[rdxDrawerIndentBackground]',
308
+ exportAs: 'rdxDrawerIndentBackground',
309
+ host: {
310
+ '[attr.data-active]': 'provider?.active() ? "" : undefined',
311
+ '[style.--nested-drawers]': 'provider?.count() ?? 0',
312
+ '[style.--drawer-frontmost-height]': '(provider?.frontmostHeight() ?? 0) + "px"'
313
+ }
314
+ }]
315
+ }] });
316
+
317
+ /**
318
+ * Resolve a snap point to the number of pixels of the drawer revealed at that point. `rootFontSize`
319
+ * (px) resolves `rem` units; it defaults to the CSS initial value of `16`.
320
+ */
321
+ function snapPointReveal(value, size, rootFontSize = 16) {
322
+ if (typeof value === 'number') {
323
+ return value > 0 && value <= 1 ? value * size : clamp(value, 0, size);
324
+ }
325
+ const trimmed = value.trim();
326
+ if (trimmed.endsWith('%')) {
327
+ return clamp((parseFloat(trimmed) / 100) * size, 0, size);
328
+ }
329
+ const parsed = parseFloat(trimmed);
330
+ if (Number.isNaN(parsed)) {
331
+ return size;
332
+ }
333
+ if (trimmed.endsWith('rem')) {
334
+ return clamp(parsed * rootFontSize, 0, size);
335
+ }
336
+ // A bare unit-less value still follows the number rule (`<= 1` is a fraction).
337
+ return trimmed.endsWith('px')
338
+ ? clamp(parsed, 0, size)
339
+ : parsed > 0 && parsed <= 1
340
+ ? parsed * size
341
+ : clamp(parsed, 0, size);
342
+ }
343
+ /**
344
+ * Build the snap entries for a given drawer size, sorted by openness (most open / smallest offset
345
+ * first). `offset = size - reveal`, so a fully-revealed point sits at offset `0`.
346
+ */
347
+ function buildSnapEntries(values, size, rootFontSize = 16) {
348
+ return values
349
+ .map((value) => {
350
+ const reveal = snapPointReveal(value, size, rootFontSize);
351
+ return { value, reveal, offset: clamp(size - reveal, 0, size) };
352
+ })
353
+ .sort((a, b) => a.offset - b.offset);
354
+ }
355
+ /** How many milliseconds of momentum a release's velocity projects forward when picking a target. */
356
+ const MOMENTUM_MS = 120;
357
+ /** Pick the snap point (or dismissal) a release lands on. */
358
+ function resolveSnapTarget(options) {
359
+ const { offsets, activeIndex, projected, velocity, size, sequential, canDismiss } = options;
360
+ if (sequential) {
361
+ const active = offsets[activeIndex] ?? 0;
362
+ if (projected > active) {
363
+ const next = activeIndex + 1 < offsets.length ? offsets[activeIndex + 1] : canDismiss ? size : active;
364
+ const midpoint = (active + next) / 2;
365
+ if (projected >= midpoint) {
366
+ if (activeIndex + 1 >= offsets.length) {
367
+ return canDismiss ? { dismiss: true } : { index: activeIndex };
368
+ }
369
+ return { index: activeIndex + 1 };
370
+ }
371
+ return { index: activeIndex };
372
+ }
373
+ const previous = activeIndex - 1 >= 0 ? offsets[activeIndex - 1] : 0;
374
+ const midpoint = (previous + active) / 2;
375
+ return projected <= midpoint && activeIndex - 1 >= 0 ? { index: activeIndex - 1 } : { index: activeIndex };
376
+ }
377
+ const target = projected + velocity * MOMENTUM_MS;
378
+ let bestIndex = 0;
379
+ let bestDistance = Infinity;
380
+ offsets.forEach((offset, index) => {
381
+ const distance = Math.abs(offset - target);
382
+ if (distance < bestDistance) {
383
+ bestDistance = distance;
384
+ bestIndex = index;
385
+ }
386
+ });
387
+ if (canDismiss && Math.abs(size - target) < bestDistance) {
388
+ return { dismiss: true };
389
+ }
390
+ return { index: bestIndex };
391
+ }
392
+ /** The unit translate vector pointing toward dismissal for a direction. */
393
+ function dismissUnitVector(direction) {
394
+ switch (direction) {
395
+ case 'down':
396
+ return { x: 0, y: 1 };
397
+ case 'up':
398
+ return { x: 0, y: -1 };
399
+ case 'right':
400
+ return { x: 1, y: 0 };
401
+ case 'left':
402
+ return { x: -1, y: 0 };
403
+ }
404
+ }
405
+
406
+ /** Pointer travel (px) before a press becomes a drag — below this a press stays a click/tap. */
407
+ const DRAG_THRESHOLD = 4;
408
+ /**
409
+ * Shared pointer-drag lifecycle for the drawer gestures (popup swipe and swipe-area open).
410
+ *
411
+ * A press only becomes a drag once the pointer moves past {@link DRAG_THRESHOLD}; until then it is a
412
+ * plain tap, so clicks on buttons inside the drawer keep working (the gesture never captures the
413
+ * pointer for a tap). Once dragging, the pointer is captured so a drag that leaves the element still
414
+ * completes, and `lostpointercapture` / `pointercancel` count as a non-committed end — a swallowed
415
+ * `pointerup` (native context menu, OS gesture, tab switch) can never wedge the gesture. No-op
416
+ * outside the browser, keeping SSR safe.
417
+ *
418
+ * Must be called from an injection context (a directive/component constructor).
419
+ */
420
+ function usePointerDrag(handlers) {
421
+ assertInInjectionContext(usePointerDrag);
422
+ if (!isPlatformBrowser(inject(PLATFORM_ID))) {
423
+ return;
424
+ }
425
+ const host = inject(ElementRef).nativeElement;
426
+ let pointerId = null;
427
+ let downEvent = null;
428
+ let dragging = false;
429
+ const removeWindowListeners = () => {
430
+ window.removeEventListener('pointermove', onPointerMove);
431
+ window.removeEventListener('pointerup', onPointerUp);
432
+ window.removeEventListener('pointercancel', onPointerUp);
433
+ };
434
+ const reset = (event, committed) => {
435
+ if (pointerId === null) {
436
+ return;
437
+ }
438
+ const wasDragging = dragging;
439
+ try {
440
+ host.releasePointerCapture?.(pointerId);
441
+ }
442
+ catch {
443
+ // Capture may already be gone (e.g. on lostpointercapture); ignore.
444
+ }
445
+ pointerId = null;
446
+ downEvent = null;
447
+ dragging = false;
448
+ removeWindowListeners();
449
+ // A press that never crossed the threshold was a tap — leave the click untouched.
450
+ if (wasDragging) {
451
+ handlers.onEnd(event, committed);
452
+ }
453
+ };
454
+ function onPointerMove(event) {
455
+ if (event.pointerId !== pointerId || !downEvent) {
456
+ return;
457
+ }
458
+ if (!dragging) {
459
+ const dx = event.clientX - downEvent.clientX;
460
+ const dy = event.clientY - downEvent.clientY;
461
+ if (Math.hypot(dx, dy) < DRAG_THRESHOLD) {
462
+ return;
463
+ }
464
+ dragging = true;
465
+ try {
466
+ host.setPointerCapture?.(pointerId);
467
+ }
468
+ catch {
469
+ // Not all environments support pointer capture; the window listeners still drive the gesture.
470
+ }
471
+ handlers.onStart(downEvent);
472
+ }
473
+ if (handlers.onMove(event) === false) {
474
+ reset(event, false);
475
+ }
476
+ }
477
+ function onPointerUp(event) {
478
+ if (event.pointerId !== pointerId) {
479
+ return;
480
+ }
481
+ reset(event, event.type === 'pointerup');
482
+ }
483
+ const onLostCapture = (event) => {
484
+ if (event.pointerId === pointerId) {
485
+ reset(event, false);
486
+ }
487
+ };
488
+ const onPointerDown = (event) => {
489
+ if (pointerId !== null || !event.isPrimary || event.button !== 0 || !handlers.canStart(event)) {
490
+ return;
491
+ }
492
+ pointerId = event.pointerId;
493
+ downEvent = event;
494
+ dragging = false;
495
+ window.addEventListener('pointermove', onPointerMove);
496
+ window.addEventListener('pointerup', onPointerUp);
497
+ window.addEventListener('pointercancel', onPointerUp);
498
+ };
499
+ host.addEventListener('pointerdown', onPointerDown);
500
+ host.addEventListener('lostpointercapture', onLostCapture);
501
+ inject(DestroyRef).onDestroy(() => {
502
+ host.removeEventListener('pointerdown', onPointerDown);
503
+ host.removeEventListener('lostpointercapture', onLostCapture);
504
+ removeWindowListeners();
505
+ });
506
+ }
507
+
508
+ /** iOS-style rubber-band resistance for dragging *past* the fully-open position. */
509
+ const RUBBER_BAND_CONSTANT = 0.55;
510
+ /** Idle time (ms) since the last movement past which a release counts as a hold, not a flick. */
511
+ const FLICK_IDLE_MS = 66;
512
+ const rubberBand = (distance, dimension) => dimension <= 0 ? 0 : (1 - 1 / ((Math.abs(distance) * RUBBER_BAND_CONSTANT) / dimension + 1)) * dimension;
513
+ const isVertical = (direction) => direction === 'up' || direction === 'down';
514
+ /**
515
+ * Whether a scrollable region between `target` and `boundary` can still scroll in the direction the
516
+ * swipe would reveal — in which case the gesture must yield to scrolling instead of dismissing.
517
+ */
518
+ function scrollGuards(target, boundary, direction) {
519
+ let node = target;
520
+ while (node && node !== boundary) {
521
+ if (node instanceof HTMLElement) {
522
+ const style = getComputedStyle(node);
523
+ const vertical = isVertical(direction);
524
+ const overflow = vertical ? style.overflowY : style.overflowX;
525
+ if (overflow === 'auto' || overflow === 'scroll') {
526
+ const scrollPos = vertical ? node.scrollTop : node.scrollLeft;
527
+ const maxScroll = vertical
528
+ ? node.scrollHeight - node.clientHeight
529
+ : node.scrollWidth - node.clientWidth;
530
+ // Pulling the drawer in the dismiss direction reveals the *start* edge for
531
+ // down/right and the *end* edge for up/left; only swipe when already at that edge.
532
+ const atStartEdge = scrollPos <= 0;
533
+ const atEndEdge = scrollPos >= maxScroll - 1;
534
+ const needsStartEdge = direction === 'down' || direction === 'right';
535
+ if (maxScroll > 0 && (needsStartEdge ? !atStartEdge : !atEndEdge)) {
536
+ return true;
537
+ }
538
+ }
539
+ }
540
+ node = node.parentElement;
541
+ }
542
+ return false;
543
+ }
544
+ /**
545
+ * Headless swipe gesture for the drawer popup: dismiss, snap-back, and movement between snap points.
546
+ *
547
+ * Writes a small contract the consumer styles against (no transform is applied for you, keeping the
548
+ * primitive headless):
549
+ * - `--drawer-swipe-movement-x` / `--drawer-swipe-movement-y` — signed px offset along the axis,
550
+ * including the active snap point's resting offset while idle.
551
+ * - `--drawer-swipe-strength` — 0..1 live dismiss progress (`0` at rest).
552
+ * - `[data-swiping]` — present while a gesture is active (drive `transition: none` off this).
553
+ * - `[data-swipe-direction]` — the active direction.
554
+ * - `[data-swipe-dismiss]` — present briefly when a release commits to dismissal.
555
+ *
556
+ * While idle the movement variables hold the active snap offset; releasing without dismissing writes
557
+ * the target offset so the consumer's `transition` animates between snap points and home.
558
+ *
559
+ * Must be called from an injection context (a directive/component constructor).
560
+ */
561
+ function useDrawerSwipe(config) {
562
+ assertInInjectionContext(useDrawerSwipe);
563
+ const element = () => config.element();
564
+ const axisSize = () => (isVertical(config.direction()) ? element().offsetHeight : element().offsetWidth);
565
+ let active = false;
566
+ let startX = 0;
567
+ let startY = 0;
568
+ let startOffset = 0;
569
+ let pendingProjected = 0;
570
+ let lastProjected = 0;
571
+ let lastTime = 0;
572
+ let velocity = 0;
573
+ let rafId = 0;
574
+ const cancelRaf = () => {
575
+ if (rafId) {
576
+ cancelAnimationFrame(rafId);
577
+ rafId = 0;
578
+ }
579
+ };
580
+ /** Write the movement variables for a translate magnitude (px) and a 0..1 dismiss strength. */
581
+ const writeMovement = (offset, strength) => {
582
+ const unit = dismissUnitVector(config.direction());
583
+ const el = element();
584
+ el.style.setProperty('--drawer-swipe-movement-x', `${unit.x * offset}px`);
585
+ el.style.setProperty('--drawer-swipe-movement-y', `${unit.y * offset}px`);
586
+ el.style.setProperty('--drawer-swipe-strength', `${strength}`);
587
+ };
588
+ const writeLive = () => {
589
+ rafId = 0;
590
+ const size = axisSize();
591
+ const visual = pendingProjected >= 0 ? pendingProjected : -rubberBand(pendingProjected, size);
592
+ const strength = clamp(pendingProjected / (size || 1), 0, 1);
593
+ writeMovement(visual, strength);
594
+ config.onProgress?.(strength);
595
+ };
596
+ const scheduleWrite = () => {
597
+ if (!rafId) {
598
+ rafId = requestAnimationFrame(writeLive);
599
+ }
600
+ };
601
+ /** Settle to a resting snap offset (animates via the consumer's transition); rest is not dismissing. */
602
+ const settleTo = (offset) => {
603
+ cancelRaf();
604
+ writeMovement(offset, 0);
605
+ config.onProgress?.(0);
606
+ };
607
+ usePointerDrag({
608
+ canStart: (event) => {
609
+ if (!config.enabled()) {
610
+ return false;
611
+ }
612
+ const target = event.target;
613
+ if (target?.closest('[data-base-ui-swipe-ignore]')) {
614
+ return false;
615
+ }
616
+ return !scrollGuards(target, element(), config.direction());
617
+ },
618
+ onStart: (event) => {
619
+ active = true;
620
+ startX = event.clientX;
621
+ startY = event.clientY;
622
+ startOffset = config.restingOffset();
623
+ pendingProjected = startOffset;
624
+ lastProjected = startOffset;
625
+ lastTime = event.timeStamp;
626
+ velocity = 0;
627
+ const el = element();
628
+ el.setAttribute('data-swiping', '');
629
+ el.removeAttribute('data-swipe-dismiss');
630
+ },
631
+ onMove: (event) => {
632
+ // Abort if the drawer closed mid-drag; the end handler settles back.
633
+ if (!config.enabled()) {
634
+ return false;
635
+ }
636
+ const unit = dismissUnitVector(config.direction());
637
+ const drag = (event.clientX - startX) * unit.x + (event.clientY - startY) * unit.y;
638
+ pendingProjected = startOffset + drag;
639
+ const dt = event.timeStamp - lastTime;
640
+ if (dt > 0) {
641
+ velocity = (pendingProjected - lastProjected) / dt;
642
+ lastProjected = pendingProjected;
643
+ lastTime = event.timeStamp;
644
+ }
645
+ scheduleWrite();
646
+ return true;
647
+ },
648
+ onEnd: (event, committed) => {
649
+ active = false;
650
+ cancelRaf();
651
+ element().removeAttribute('data-swiping');
652
+ // A pause before lift is a hold, not a flick: drop stale velocity.
653
+ if (event.timeStamp - lastTime > FLICK_IDLE_MS) {
654
+ velocity = 0;
655
+ }
656
+ const release = config.resolveRelease(pendingProjected, velocity, committed && config.enabled());
657
+ if (release.type === 'dismiss') {
658
+ element().setAttribute('data-swipe-dismiss', '');
659
+ config.onDismiss(event);
660
+ return;
661
+ }
662
+ settleTo(release.offset);
663
+ }
664
+ });
665
+ // Keep the idle resting offset in sync with snap state and reset live progress to 0 at rest.
666
+ // Skipped while dragging (the gesture owns the variables) and writes nothing while closed so the
667
+ // exit keyframe starts from the last visible offset.
668
+ effect(() => {
669
+ const offset = config.restingOffset();
670
+ const enabled = config.enabled();
671
+ if (active) {
672
+ return;
673
+ }
674
+ if (enabled) {
675
+ writeMovement(offset, 0);
676
+ }
677
+ config.onProgress?.(0);
678
+ });
679
+ inject(DestroyRef).onDestroy(cancelRaf);
680
+ }
681
+
682
+ /** Fraction of the drawer size a plain (no-snap) release must pass to dismiss. */
683
+ const DISMISS_FRACTION = 0.5;
684
+ /** Dismiss-axis velocity (px/ms) past which a plain release dismisses regardless of distance. */
685
+ const DISMISS_VELOCITY = 0.4;
686
+ /** Root font size (px) for resolving `rem` snap points; `16` (the CSS initial value) outside the browser. */
687
+ function rootFontSize() {
688
+ if (typeof document === 'undefined') {
689
+ return 16;
690
+ }
691
+ return parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;
692
+ }
693
+ /**
694
+ * A container for the drawer contents.
695
+ *
696
+ * Composes the dialog popup (focus trap, dismissal, scroll lock, a11y wiring) and owns the drawer
697
+ * gesture on top of it: swipe-to-dismiss, snap-back, and movement between snap points. The gesture
698
+ * publishes a CSS-variable / data-attribute contract (see {@link useDrawerSwipe}); the consumer
699
+ * styles the actual transform and snap-back transition off it, keeping the primitive headless.
700
+ */
701
+ class RdxDrawerPopup {
702
+ constructor() {
703
+ this.drawerContext = injectRdxDrawerRootContext();
704
+ this.dialogContext = injectRdxDialogRootContext();
705
+ this.elementRef = inject(ElementRef);
706
+ this.element = this.elementRef.nativeElement;
707
+ /** Live popup size (px); a ResizeObserver keeps it current so snap geometry never goes stale. */
708
+ this.size = elementSize({ elementRef: this.elementRef, injector: inject(Injector) });
709
+ /** Snap entries for the current size; built once and shared by the offset/expanded reads. */
710
+ this.snapEntries = computed(() => buildSnapEntries(this.drawerContext.snapPoints(), this.axisSize(), rootFontSize()), ...(ngDevMode ? [{ debugName: "snapEntries" }] : /* istanbul ignore next */ []));
711
+ /** Resting translate magnitude (px) of the active snap point; `0` when fully open / no snaps. */
712
+ this.restingOffset = computed(() => {
713
+ const active = this.drawerContext.activeSnapPoint();
714
+ if (active === null || !this.drawerContext.hasSnapPoints()) {
715
+ return 0;
716
+ }
717
+ return this.snapEntries().find((candidate) => candidate.value === active)?.offset ?? 0;
718
+ }, ...(ngDevMode ? [{ debugName: "restingOffset" }] : /* istanbul ignore next */ []));
719
+ /** Whether the active snap point is the most open one. */
720
+ this.expanded = computed(() => {
721
+ const active = this.drawerContext.activeSnapPoint();
722
+ if (active === null || !this.drawerContext.hasSnapPoints()) {
723
+ return false;
724
+ }
725
+ const entries = this.snapEntries();
726
+ return entries.length > 0 && entries[0].value === active;
727
+ }, ...(ngDevMode ? [{ debugName: "expanded" }] : /* istanbul ignore next */ []));
728
+ /** The frontmost nested drawer's height for `--drawer-frontmost-height`, or unset when none. */
729
+ this.frontmostHeightPx = computed(() => {
730
+ const height = this.drawerContext.frontmostHeight();
731
+ return this.drawerContext.nestedDrawerOpen() && height > 0 ? `${height}px` : null;
732
+ }, ...(ngDevMode ? [{ debugName: "frontmostHeightPx" }] : /* istanbul ignore next */ []));
733
+ useDrawerSwipe({
734
+ element: () => this.element,
735
+ direction: this.drawerContext.swipeDirection,
736
+ enabled: computed(() => this.dialogContext.isOpen()),
737
+ restingOffset: this.restingOffset,
738
+ resolveRelease: (projected, velocity, canDismiss) => this.resolveRelease(projected, velocity, canDismiss),
739
+ onDismiss: (event) => this.dialogContext.close('swipe', event),
740
+ onProgress: (strength) => this.drawerContext.setSwipeProgress(strength)
741
+ });
742
+ // Publish informational snap variables and report the measured size to the provider.
743
+ effect(() => {
744
+ const offset = this.restingOffset();
745
+ const size = this.axisSize();
746
+ if (!this.dialogContext.isOpen()) {
747
+ return;
748
+ }
749
+ this.element.style.setProperty('--drawer-height', `${size}px`);
750
+ this.element.style.setProperty('--drawer-snap-point-offset', `${offset}px`);
751
+ this.drawerContext.reportPopupHeight(size);
752
+ });
753
+ }
754
+ axisSize() {
755
+ const direction = this.drawerContext.swipeDirection();
756
+ const size = this.size();
757
+ return direction === 'up' || direction === 'down' ? size.height : size.width;
758
+ }
759
+ resolveRelease(projected, velocity, canDismiss) {
760
+ const size = this.axisSize();
761
+ const dismissAllowed = canDismiss && !this.dialogContext.disablePointerDismissal();
762
+ if (!this.drawerContext.hasSnapPoints()) {
763
+ const strength = projected / (size || 1);
764
+ return dismissAllowed && (strength >= DISMISS_FRACTION || velocity >= DISMISS_VELOCITY)
765
+ ? { type: 'dismiss' }
766
+ : { type: 'snap', offset: 0 };
767
+ }
768
+ const entries = this.snapEntries();
769
+ const offsets = entries.map((entry) => entry.offset);
770
+ const active = this.drawerContext.activeSnapPoint();
771
+ const activeIndex = Math.max(0, entries.findIndex((entry) => entry.value === active));
772
+ const target = resolveSnapTarget({
773
+ offsets,
774
+ activeIndex,
775
+ projected,
776
+ velocity,
777
+ size,
778
+ sequential: this.drawerContext.sequentialSnap(),
779
+ canDismiss: dismissAllowed
780
+ });
781
+ if ('dismiss' in target) {
782
+ return { type: 'dismiss' };
783
+ }
784
+ const entry = entries[target.index];
785
+ if (entry.value !== active) {
786
+ this.drawerContext.setActiveSnapPoint(entry.value, true);
787
+ }
788
+ return { type: 'snap', offset: entry.offset };
789
+ }
790
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerPopup, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
791
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxDrawerPopup, isStandalone: true, selector: "[rdxDrawerPopup]", host: { properties: { "attr.data-swipe-direction": "drawerContext.swipeDirection()", "attr.data-expanded": "expanded() ? \"\" : undefined", "attr.data-nested-drawer-open": "drawerContext.nestedDrawerOpen() ? \"\" : undefined", "style.--nested-drawers": "drawerContext.nestedDrawerCount()", "style.--drawer-frontmost-height": "frontmostHeightPx()" } }, exportAs: ["rdxDrawerPopup"], hostDirectives: [{ directive: i1.RdxDialogPopup, outputs: ["escapeKeyDown", "escapeKeyDown", "pointerDownOutside", "pointerDownOutside", "focusOutside", "focusOutside", "interactOutside", "interactOutside", "openAutoFocus", "openAutoFocus", "closeAutoFocus", "closeAutoFocus"] }], ngImport: i0 }); }
792
+ }
793
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerPopup, decorators: [{
794
+ type: Directive,
795
+ args: [{
796
+ selector: '[rdxDrawerPopup]',
797
+ exportAs: 'rdxDrawerPopup',
798
+ hostDirectives: [
799
+ {
800
+ directive: RdxDialogPopup,
801
+ outputs: [
802
+ 'escapeKeyDown',
803
+ 'pointerDownOutside',
804
+ 'focusOutside',
805
+ 'interactOutside',
806
+ 'openAutoFocus',
807
+ 'closeAutoFocus'
808
+ ]
809
+ }
810
+ ],
811
+ host: {
812
+ '[attr.data-swipe-direction]': 'drawerContext.swipeDirection()',
813
+ '[attr.data-expanded]': 'expanded() ? "" : undefined',
814
+ '[attr.data-nested-drawer-open]': 'drawerContext.nestedDrawerOpen() ? "" : undefined',
815
+ '[style.--nested-drawers]': 'drawerContext.nestedDrawerCount()',
816
+ '[style.--drawer-frontmost-height]': 'frontmostHeightPx()'
817
+ }
818
+ }]
819
+ }], ctorParameters: () => [] });
820
+
821
+ /**
822
+ * Moves the drawer to a different part of the DOM. Defaults to `document.body`.
823
+ */
824
+ class RdxDrawerPortal {
825
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerPortal, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
826
+ 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 }); }
827
+ }
828
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerPortal, decorators: [{
829
+ type: Directive,
830
+ args: [{
831
+ selector: '[rdxDrawerPortal]',
832
+ exportAs: 'rdxDrawerPortal',
833
+ hostDirectives: [
834
+ {
835
+ directive: RdxDialogPortal,
836
+ inputs: ['container']
837
+ }
838
+ ]
839
+ }]
840
+ }] });
841
+
842
+ /**
843
+ * Mounts the portal while the drawer is open and waits for CSS exit keyframes before unmounting.
844
+ */
845
+ class RdxDrawerPortalPresence {
846
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerPortalPresence, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
847
+ 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 }); }
848
+ }
849
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerPortalPresence, decorators: [{
850
+ type: Directive,
851
+ args: [{
852
+ selector: 'ng-template[rdxDrawerPortalPresence]',
853
+ hostDirectives: [RdxDialogPortalPresence]
854
+ }]
855
+ }] });
856
+
857
+ /** Pointer travel (px) inward past which the swipe area opens the drawer. */
858
+ const OPEN_THRESHOLD = 30;
859
+ /** Inward pointer travel (toward the open drawer) for a given direction and pointer delta. */
860
+ function inwardDistance(direction, dx, dy) {
861
+ switch (direction) {
862
+ case 'down':
863
+ return -dy;
864
+ case 'up':
865
+ return dy;
866
+ case 'left':
867
+ return dx;
868
+ case 'right':
869
+ return -dx;
870
+ }
871
+ }
872
+ /**
873
+ * An off-canvas region (typically pinned to a screen edge) that opens the drawer when swiped inward.
874
+ *
875
+ * Phase 1 opens on a threshold crossing rather than following the pointer live (the popup is not
876
+ * mounted while closed); the live-follow open will land with snap points. Shares the drawer's
877
+ * pointer-drag lifecycle so capture/cancel handling stays consistent with the popup gesture.
878
+ */
879
+ class RdxDrawerSwipeArea {
880
+ constructor() {
881
+ this.drawerContext = injectRdxDrawerRootContext();
882
+ this.dialogContext = injectRdxDialogRootContext();
883
+ /** Direction the swipe area opens from; defaults to the root's `swipeDirection`. */
884
+ this.swipeDirection = input(...(ngDevMode ? [undefined, { debugName: "swipeDirection" }] : /* istanbul ignore next */ []));
885
+ /** Whether the swipe area should ignore user interaction. */
886
+ this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
887
+ this.isOpen = computed(() => this.dialogContext.isOpen(), ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
888
+ this.direction = computed(() => this.swipeDirection() ?? this.drawerContext.swipeDirection(), ...(ngDevMode ? [{ debugName: "direction" }] : /* istanbul ignore next */ []));
889
+ this.swiping = signal(false, ...(ngDevMode ? [{ debugName: "swiping" }] : /* istanbul ignore next */ []));
890
+ this.startX = 0;
891
+ this.startY = 0;
892
+ usePointerDrag({
893
+ canStart: () => !this.disabled() && !this.isOpen(),
894
+ onStart: (event) => {
895
+ this.startX = event.clientX;
896
+ this.startY = event.clientY;
897
+ this.swiping.set(true);
898
+ },
899
+ onMove: (event) => {
900
+ if (this.disabled()) {
901
+ return false;
902
+ }
903
+ const distance = inwardDistance(this.direction(), event.clientX - this.startX, event.clientY - this.startY);
904
+ if (distance >= OPEN_THRESHOLD) {
905
+ this.dialogContext.open(undefined, undefined, undefined, 'swipe', event);
906
+ return false;
907
+ }
908
+ return true;
909
+ },
910
+ onEnd: () => this.swiping.set(false)
911
+ });
912
+ }
913
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerSwipeArea, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
914
+ 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 }); }
915
+ }
916
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerSwipeArea, decorators: [{
917
+ type: Directive,
918
+ args: [{
919
+ selector: '[rdxDrawerSwipeArea]',
920
+ exportAs: 'rdxDrawerSwipeArea',
921
+ host: {
922
+ '[attr.data-open]': 'isOpen() ? "" : undefined',
923
+ '[attr.data-closed]': 'isOpen() ? undefined : ""',
924
+ '[attr.data-disabled]': 'disabled() ? "" : undefined',
925
+ '[attr.data-swiping]': 'swiping() ? "" : undefined',
926
+ '[attr.data-swipe-direction]': 'direction()'
927
+ }
928
+ }]
929
+ }], ctorParameters: () => [], propDecorators: { swipeDirection: [{ type: i0.Input, args: [{ isSignal: true, alias: "swipeDirection", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
930
+
931
+ /**
932
+ * An accessible title announced when the drawer is opened.
933
+ */
934
+ class RdxDrawerTitle {
935
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerTitle, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
936
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxDrawerTitle, isStandalone: true, selector: "[rdxDrawerTitle]", exportAs: ["rdxDrawerTitle"], hostDirectives: [{ directive: i1.RdxDialogTitle }], ngImport: i0 }); }
937
+ }
938
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerTitle, decorators: [{
939
+ type: Directive,
940
+ args: [{
941
+ selector: '[rdxDrawerTitle]',
942
+ exportAs: 'rdxDrawerTitle',
943
+ hostDirectives: [RdxDialogTitle]
944
+ }]
945
+ }] });
946
+
947
+ /**
948
+ * A button that opens the drawer. Behaves exactly like the dialog trigger.
949
+ */
950
+ class RdxDrawerTrigger {
951
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
952
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxDrawerTrigger, isStandalone: true, selector: "button[rdxDrawerTrigger]", exportAs: ["rdxDrawerTrigger"], hostDirectives: [{ directive: i1.RdxDialogTrigger, inputs: ["handle", "handle", "payload", "payload", "id", "id", "disabled", "disabled"] }], ngImport: i0 }); }
953
+ }
954
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerTrigger, decorators: [{
955
+ type: Directive,
956
+ args: [{
957
+ selector: 'button[rdxDrawerTrigger]',
958
+ exportAs: 'rdxDrawerTrigger',
959
+ hostDirectives: [
960
+ {
961
+ directive: RdxDialogTrigger,
962
+ inputs: ['handle', 'payload', 'id', 'disabled']
963
+ }
964
+ ]
965
+ }]
966
+ }] });
967
+
968
+ /**
969
+ * A positioning container for the drawer popup that can be made scrollable.
970
+ *
971
+ * Exposes the dialog viewport's `data-nested` / `data-nested-dialog-open` state for styling.
972
+ */
973
+ class RdxDrawerViewport {
974
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerViewport, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
975
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxDrawerViewport, isStandalone: true, selector: "[rdxDrawerViewport]", exportAs: ["rdxDrawerViewport"], hostDirectives: [{ directive: i1.RdxDialogViewport }], ngImport: i0 }); }
976
+ }
977
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerViewport, decorators: [{
978
+ type: Directive,
979
+ args: [{
980
+ selector: '[rdxDrawerViewport]',
981
+ exportAs: 'rdxDrawerViewport',
982
+ hostDirectives: [RdxDialogViewport]
983
+ }]
984
+ }] });
985
+
986
+ /**
987
+ * Connects a drawer root with trigger elements rendered elsewhere in the DOM.
988
+ *
989
+ * Drawers reuse the dialog handle implementation unchanged.
990
+ */
991
+ const RdxDrawerHandle = RdxDialogHandle;
992
+ function createRdxDrawerHandle() {
993
+ return createRdxDialogHandle();
994
+ }
995
+
996
+ const drawerImports = [
997
+ RdxDrawerProviderDirective,
998
+ RdxDrawerRoot,
999
+ RdxDrawerTrigger,
1000
+ RdxDrawerSwipeArea,
1001
+ RdxDrawerPortalPresence,
1002
+ RdxDrawerPortal,
1003
+ RdxDrawerBackdrop,
1004
+ RdxDrawerViewport,
1005
+ RdxDrawerPopup,
1006
+ RdxDrawerContent,
1007
+ RdxDrawerTitle,
1008
+ RdxDrawerDescription,
1009
+ RdxDrawerClose,
1010
+ RdxDrawerIndent,
1011
+ RdxDrawerIndentBackground
1012
+ ];
1013
+ class RdxDrawerModule {
1014
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1015
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerModule, imports: [RdxDrawerProviderDirective,
1016
+ RdxDrawerRoot,
1017
+ RdxDrawerTrigger,
1018
+ RdxDrawerSwipeArea,
1019
+ RdxDrawerPortalPresence,
1020
+ RdxDrawerPortal,
1021
+ RdxDrawerBackdrop,
1022
+ RdxDrawerViewport,
1023
+ RdxDrawerPopup,
1024
+ RdxDrawerContent,
1025
+ RdxDrawerTitle,
1026
+ RdxDrawerDescription,
1027
+ RdxDrawerClose,
1028
+ RdxDrawerIndent,
1029
+ RdxDrawerIndentBackground], exports: [RdxDrawerProviderDirective,
1030
+ RdxDrawerRoot,
1031
+ RdxDrawerTrigger,
1032
+ RdxDrawerSwipeArea,
1033
+ RdxDrawerPortalPresence,
1034
+ RdxDrawerPortal,
1035
+ RdxDrawerBackdrop,
1036
+ RdxDrawerViewport,
1037
+ RdxDrawerPopup,
1038
+ RdxDrawerContent,
1039
+ RdxDrawerTitle,
1040
+ RdxDrawerDescription,
1041
+ RdxDrawerClose,
1042
+ RdxDrawerIndent,
1043
+ RdxDrawerIndentBackground] }); }
1044
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerModule }); }
1045
+ }
1046
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxDrawerModule, decorators: [{
1047
+ type: NgModule,
1048
+ args: [{
1049
+ imports: [...drawerImports],
1050
+ exports: [...drawerImports]
1051
+ }]
1052
+ }] });
1053
+
1054
+ /**
1055
+ * Generated bundle index. Do not edit.
1056
+ */
1057
+
1058
+ 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, usePointerDrag };
1059
+ //# sourceMappingURL=radix-ng-primitives-drawer.mjs.map