@cdevhub/ngx-tw 0.4.0 → 0.6.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 (209) hide show
  1. package/README.md +78 -15
  2. package/fesm2022/cdevhub-ngx-tw-accordion.mjs +16 -5
  3. package/fesm2022/cdevhub-ngx-tw-accordion.mjs.map +1 -1
  4. package/fesm2022/cdevhub-ngx-tw-avatar.mjs +26 -15
  5. package/fesm2022/cdevhub-ngx-tw-avatar.mjs.map +1 -1
  6. package/fesm2022/cdevhub-ngx-tw-badge.mjs +17 -5
  7. package/fesm2022/cdevhub-ngx-tw-badge.mjs.map +1 -1
  8. package/fesm2022/cdevhub-ngx-tw-breadcrumbs.mjs +27 -6
  9. package/fesm2022/cdevhub-ngx-tw-breadcrumbs.mjs.map +1 -1
  10. package/fesm2022/cdevhub-ngx-tw-button.mjs +23 -11
  11. package/fesm2022/cdevhub-ngx-tw-button.mjs.map +1 -1
  12. package/fesm2022/cdevhub-ngx-tw-calendar-luxon.mjs +5 -5
  13. package/fesm2022/cdevhub-ngx-tw-calendar-luxon.mjs.map +1 -1
  14. package/fesm2022/cdevhub-ngx-tw-calendar-testing.mjs +3 -3
  15. package/fesm2022/cdevhub-ngx-tw-calendar-testing.mjs.map +1 -1
  16. package/fesm2022/cdevhub-ngx-tw-calendar.mjs +427 -122
  17. package/fesm2022/cdevhub-ngx-tw-calendar.mjs.map +1 -1
  18. package/fesm2022/cdevhub-ngx-tw-card.mjs +21 -11
  19. package/fesm2022/cdevhub-ngx-tw-card.mjs.map +1 -1
  20. package/fesm2022/cdevhub-ngx-tw-carousel.mjs +215 -96
  21. package/fesm2022/cdevhub-ngx-tw-carousel.mjs.map +1 -1
  22. package/fesm2022/cdevhub-ngx-tw-checkbox.mjs +108 -64
  23. package/fesm2022/cdevhub-ngx-tw-checkbox.mjs.map +1 -1
  24. package/fesm2022/cdevhub-ngx-tw-code-block.mjs +18 -6
  25. package/fesm2022/cdevhub-ngx-tw-code-block.mjs.map +1 -1
  26. package/fesm2022/cdevhub-ngx-tw-collapsible.mjs +55 -30
  27. package/fesm2022/cdevhub-ngx-tw-collapsible.mjs.map +1 -1
  28. package/fesm2022/cdevhub-ngx-tw-combobox-testing.mjs +218 -0
  29. package/fesm2022/cdevhub-ngx-tw-combobox-testing.mjs.map +1 -0
  30. package/fesm2022/cdevhub-ngx-tw-combobox.mjs +236 -211
  31. package/fesm2022/cdevhub-ngx-tw-combobox.mjs.map +1 -1
  32. package/fesm2022/cdevhub-ngx-tw-command-palette-testing.mjs +200 -0
  33. package/fesm2022/cdevhub-ngx-tw-command-palette-testing.mjs.map +1 -0
  34. package/fesm2022/cdevhub-ngx-tw-command-palette.mjs +34 -7
  35. package/fesm2022/cdevhub-ngx-tw-command-palette.mjs.map +1 -1
  36. package/fesm2022/cdevhub-ngx-tw-core.mjs +135 -15
  37. package/fesm2022/cdevhub-ngx-tw-core.mjs.map +1 -1
  38. package/fesm2022/cdevhub-ngx-tw-date-picker-testing.mjs +203 -0
  39. package/fesm2022/cdevhub-ngx-tw-date-picker-testing.mjs.map +1 -0
  40. package/fesm2022/cdevhub-ngx-tw-date-picker.mjs +160 -102
  41. package/fesm2022/cdevhub-ngx-tw-date-picker.mjs.map +1 -1
  42. package/fesm2022/cdevhub-ngx-tw-date-range-picker-testing.mjs +209 -0
  43. package/fesm2022/cdevhub-ngx-tw-date-range-picker-testing.mjs.map +1 -0
  44. package/fesm2022/cdevhub-ngx-tw-date-range-picker.mjs +182 -107
  45. package/fesm2022/cdevhub-ngx-tw-date-range-picker.mjs.map +1 -1
  46. package/fesm2022/cdevhub-ngx-tw-dialog-dialog-renderer-DoIhoV3d.mjs +198 -0
  47. package/fesm2022/cdevhub-ngx-tw-dialog-dialog-renderer-DoIhoV3d.mjs.map +1 -0
  48. package/fesm2022/cdevhub-ngx-tw-dialog-testing.mjs +122 -0
  49. package/fesm2022/cdevhub-ngx-tw-dialog-testing.mjs.map +1 -0
  50. package/fesm2022/cdevhub-ngx-tw-dialog.mjs +199 -220
  51. package/fesm2022/cdevhub-ngx-tw-dialog.mjs.map +1 -1
  52. package/fesm2022/cdevhub-ngx-tw-empty-state.mjs +1 -1
  53. package/fesm2022/cdevhub-ngx-tw-empty-state.mjs.map +1 -1
  54. package/fesm2022/cdevhub-ngx-tw-file-upload-testing.mjs +149 -0
  55. package/fesm2022/cdevhub-ngx-tw-file-upload-testing.mjs.map +1 -0
  56. package/fesm2022/cdevhub-ngx-tw-file-upload.mjs +57 -67
  57. package/fesm2022/cdevhub-ngx-tw-file-upload.mjs.map +1 -1
  58. package/fesm2022/cdevhub-ngx-tw-flip-card.mjs +42 -24
  59. package/fesm2022/cdevhub-ngx-tw-flip-card.mjs.map +1 -1
  60. package/fesm2022/cdevhub-ngx-tw-form-field.mjs +114 -21
  61. package/fesm2022/cdevhub-ngx-tw-form-field.mjs.map +1 -1
  62. package/fesm2022/cdevhub-ngx-tw-icon.mjs +16 -6
  63. package/fesm2022/cdevhub-ngx-tw-icon.mjs.map +1 -1
  64. package/fesm2022/cdevhub-ngx-tw-input.mjs +52 -61
  65. package/fesm2022/cdevhub-ngx-tw-input.mjs.map +1 -1
  66. package/fesm2022/cdevhub-ngx-tw-item.mjs +18 -3
  67. package/fesm2022/cdevhub-ngx-tw-item.mjs.map +1 -1
  68. package/fesm2022/cdevhub-ngx-tw-menu-testing.mjs +168 -0
  69. package/fesm2022/cdevhub-ngx-tw-menu-testing.mjs.map +1 -0
  70. package/fesm2022/cdevhub-ngx-tw-menu.mjs +58 -21
  71. package/fesm2022/cdevhub-ngx-tw-menu.mjs.map +1 -1
  72. package/fesm2022/cdevhub-ngx-tw-number-input.mjs +34 -1
  73. package/fesm2022/cdevhub-ngx-tw-number-input.mjs.map +1 -1
  74. package/fesm2022/cdevhub-ngx-tw-paginator.mjs +95 -45
  75. package/fesm2022/cdevhub-ngx-tw-paginator.mjs.map +1 -1
  76. package/fesm2022/cdevhub-ngx-tw-popover.mjs +81 -32
  77. package/fesm2022/cdevhub-ngx-tw-popover.mjs.map +1 -1
  78. package/fesm2022/cdevhub-ngx-tw-progress-bar.mjs +1 -1
  79. package/fesm2022/cdevhub-ngx-tw-progress-bar.mjs.map +1 -1
  80. package/fesm2022/cdevhub-ngx-tw-radio.mjs +131 -98
  81. package/fesm2022/cdevhub-ngx-tw-radio.mjs.map +1 -1
  82. package/fesm2022/cdevhub-ngx-tw-segmented-control.mjs +207 -42
  83. package/fesm2022/cdevhub-ngx-tw-segmented-control.mjs.map +1 -1
  84. package/fesm2022/cdevhub-ngx-tw-select-testing.mjs +165 -0
  85. package/fesm2022/cdevhub-ngx-tw-select-testing.mjs.map +1 -0
  86. package/fesm2022/cdevhub-ngx-tw-select.mjs +386 -210
  87. package/fesm2022/cdevhub-ngx-tw-select.mjs.map +1 -1
  88. package/fesm2022/cdevhub-ngx-tw-sheet-sheet-renderer-CqVJwgmp.mjs +256 -0
  89. package/fesm2022/cdevhub-ngx-tw-sheet-sheet-renderer-CqVJwgmp.mjs.map +1 -0
  90. package/fesm2022/cdevhub-ngx-tw-sheet-testing.mjs +129 -0
  91. package/fesm2022/cdevhub-ngx-tw-sheet-testing.mjs.map +1 -0
  92. package/fesm2022/cdevhub-ngx-tw-sheet.mjs +197 -278
  93. package/fesm2022/cdevhub-ngx-tw-sheet.mjs.map +1 -1
  94. package/fesm2022/cdevhub-ngx-tw-slider.mjs +89 -54
  95. package/fesm2022/cdevhub-ngx-tw-slider.mjs.map +1 -1
  96. package/fesm2022/cdevhub-ngx-tw-sort.mjs +122 -17
  97. package/fesm2022/cdevhub-ngx-tw-sort.mjs.map +1 -1
  98. package/fesm2022/cdevhub-ngx-tw-split.mjs +72 -19
  99. package/fesm2022/cdevhub-ngx-tw-split.mjs.map +1 -1
  100. package/fesm2022/cdevhub-ngx-tw-stat.mjs +63 -25
  101. package/fesm2022/cdevhub-ngx-tw-stat.mjs.map +1 -1
  102. package/fesm2022/cdevhub-ngx-tw-stepper.mjs +35 -8
  103. package/fesm2022/cdevhub-ngx-tw-stepper.mjs.map +1 -1
  104. package/fesm2022/cdevhub-ngx-tw-switch.mjs +54 -48
  105. package/fesm2022/cdevhub-ngx-tw-switch.mjs.map +1 -1
  106. package/fesm2022/cdevhub-ngx-tw-tab-nav.mjs +12 -15
  107. package/fesm2022/cdevhub-ngx-tw-tab-nav.mjs.map +1 -1
  108. package/fesm2022/cdevhub-ngx-tw-table.mjs +74 -13
  109. package/fesm2022/cdevhub-ngx-tw-table.mjs.map +1 -1
  110. package/fesm2022/cdevhub-ngx-tw-tabs.mjs +84 -30
  111. package/fesm2022/cdevhub-ngx-tw-tabs.mjs.map +1 -1
  112. package/fesm2022/cdevhub-ngx-tw-tags-input-testing.mjs +172 -0
  113. package/fesm2022/cdevhub-ngx-tw-tags-input-testing.mjs.map +1 -0
  114. package/fesm2022/cdevhub-ngx-tw-tags-input.mjs +107 -71
  115. package/fesm2022/cdevhub-ngx-tw-tags-input.mjs.map +1 -1
  116. package/fesm2022/cdevhub-ngx-tw-textarea.mjs +41 -9
  117. package/fesm2022/cdevhub-ngx-tw-textarea.mjs.map +1 -1
  118. package/fesm2022/cdevhub-ngx-tw-theme.mjs +257 -45
  119. package/fesm2022/cdevhub-ngx-tw-theme.mjs.map +1 -1
  120. package/fesm2022/cdevhub-ngx-tw-time-picker-testing.mjs +201 -0
  121. package/fesm2022/cdevhub-ngx-tw-time-picker-testing.mjs.map +1 -0
  122. package/fesm2022/cdevhub-ngx-tw-time-picker.mjs +184 -77
  123. package/fesm2022/cdevhub-ngx-tw-time-picker.mjs.map +1 -1
  124. package/fesm2022/cdevhub-ngx-tw-timeline.mjs +110 -27
  125. package/fesm2022/cdevhub-ngx-tw-timeline.mjs.map +1 -1
  126. package/fesm2022/cdevhub-ngx-tw-toast-toast-renderer-BlDxemsU.mjs +616 -0
  127. package/fesm2022/cdevhub-ngx-tw-toast-toast-renderer-BlDxemsU.mjs.map +1 -0
  128. package/fesm2022/cdevhub-ngx-tw-toast.mjs +556 -945
  129. package/fesm2022/cdevhub-ngx-tw-toast.mjs.map +1 -1
  130. package/fesm2022/cdevhub-ngx-tw-tooltip.mjs +102 -15
  131. package/fesm2022/cdevhub-ngx-tw-tooltip.mjs.map +1 -1
  132. package/fesm2022/cdevhub-ngx-tw-transfer-testing.mjs +219 -0
  133. package/fesm2022/cdevhub-ngx-tw-transfer-testing.mjs.map +1 -0
  134. package/fesm2022/cdevhub-ngx-tw-transfer.mjs +88 -69
  135. package/fesm2022/cdevhub-ngx-tw-transfer.mjs.map +1 -1
  136. package/fesm2022/cdevhub-ngx-tw-tree.mjs +68 -19
  137. package/fesm2022/cdevhub-ngx-tw-tree.mjs.map +1 -1
  138. package/index.json +1 -1
  139. package/package.json +63 -2
  140. package/theme/_base.css +13 -0
  141. package/theme/_dark.css +110 -36
  142. package/theme/_high-contrast-dark.css +367 -0
  143. package/theme/_high-contrast.css +13 -2
  144. package/theme/_light.css +276 -0
  145. package/theme/_semantic.css +47 -12
  146. package/theme/_typography.css +17 -0
  147. package/theme/index.css +86 -7
  148. package/types/cdevhub-ngx-tw-accordion.d.ts +12 -4
  149. package/types/cdevhub-ngx-tw-avatar.d.ts +10 -3
  150. package/types/cdevhub-ngx-tw-button.d.ts +1 -0
  151. package/types/cdevhub-ngx-tw-calendar-luxon.d.ts +2 -2
  152. package/types/cdevhub-ngx-tw-calendar-testing.d.ts +1 -1
  153. package/types/cdevhub-ngx-tw-calendar.d.ts +179 -73
  154. package/types/cdevhub-ngx-tw-card.d.ts +11 -3
  155. package/types/cdevhub-ngx-tw-carousel.d.ts +89 -20
  156. package/types/cdevhub-ngx-tw-checkbox.d.ts +40 -12
  157. package/types/cdevhub-ngx-tw-code-block.d.ts +11 -2
  158. package/types/cdevhub-ngx-tw-collapsible.d.ts +32 -5
  159. package/types/cdevhub-ngx-tw-combobox-testing.d.ts +157 -0
  160. package/types/cdevhub-ngx-tw-combobox.d.ts +94 -53
  161. package/types/cdevhub-ngx-tw-command-palette-testing.d.ts +136 -0
  162. package/types/cdevhub-ngx-tw-command-palette.d.ts +33 -5
  163. package/types/cdevhub-ngx-tw-core.d.ts +152 -21
  164. package/types/cdevhub-ngx-tw-date-picker-testing.d.ts +141 -0
  165. package/types/cdevhub-ngx-tw-date-picker.d.ts +37 -29
  166. package/types/cdevhub-ngx-tw-date-range-picker-testing.d.ts +148 -0
  167. package/types/cdevhub-ngx-tw-date-range-picker.d.ts +36 -29
  168. package/types/cdevhub-ngx-tw-dialog-testing.d.ts +98 -0
  169. package/types/cdevhub-ngx-tw-dialog.d.ts +89 -19
  170. package/types/cdevhub-ngx-tw-file-upload-testing.d.ts +120 -0
  171. package/types/cdevhub-ngx-tw-file-upload.d.ts +8 -10
  172. package/types/cdevhub-ngx-tw-flip-card.d.ts +18 -11
  173. package/types/cdevhub-ngx-tw-form-field.d.ts +19 -2
  174. package/types/cdevhub-ngx-tw-icon.d.ts +3 -3
  175. package/types/cdevhub-ngx-tw-input.d.ts +5 -8
  176. package/types/cdevhub-ngx-tw-item.d.ts +2 -0
  177. package/types/cdevhub-ngx-tw-menu-testing.d.ts +131 -0
  178. package/types/cdevhub-ngx-tw-menu.d.ts +2 -2
  179. package/types/cdevhub-ngx-tw-number-input.d.ts +20 -0
  180. package/types/cdevhub-ngx-tw-paginator.d.ts +58 -24
  181. package/types/cdevhub-ngx-tw-popover.d.ts +41 -10
  182. package/types/cdevhub-ngx-tw-progress-bar.d.ts +1 -1
  183. package/types/cdevhub-ngx-tw-radio.d.ts +68 -25
  184. package/types/cdevhub-ngx-tw-segmented-control.d.ts +79 -16
  185. package/types/cdevhub-ngx-tw-select-testing.d.ts +114 -0
  186. package/types/cdevhub-ngx-tw-select.d.ts +104 -33
  187. package/types/cdevhub-ngx-tw-sheet-testing.d.ts +104 -0
  188. package/types/cdevhub-ngx-tw-sheet.d.ts +96 -21
  189. package/types/cdevhub-ngx-tw-slider.d.ts +79 -25
  190. package/types/cdevhub-ngx-tw-sort.d.ts +45 -4
  191. package/types/cdevhub-ngx-tw-split.d.ts +32 -2
  192. package/types/cdevhub-ngx-tw-stat.d.ts +14 -4
  193. package/types/cdevhub-ngx-tw-stepper.d.ts +16 -2
  194. package/types/cdevhub-ngx-tw-switch.d.ts +35 -13
  195. package/types/cdevhub-ngx-tw-tab-nav.d.ts +7 -6
  196. package/types/cdevhub-ngx-tw-table.d.ts +53 -10
  197. package/types/cdevhub-ngx-tw-tabs.d.ts +41 -10
  198. package/types/cdevhub-ngx-tw-tags-input-testing.d.ts +135 -0
  199. package/types/cdevhub-ngx-tw-tags-input.d.ts +26 -11
  200. package/types/cdevhub-ngx-tw-textarea.d.ts +3 -2
  201. package/types/cdevhub-ngx-tw-theme.d.ts +245 -39
  202. package/types/cdevhub-ngx-tw-time-picker-testing.d.ts +129 -0
  203. package/types/cdevhub-ngx-tw-time-picker.d.ts +76 -19
  204. package/types/cdevhub-ngx-tw-timeline.d.ts +36 -12
  205. package/types/cdevhub-ngx-tw-toast.d.ts +61 -12
  206. package/types/cdevhub-ngx-tw-tooltip.d.ts +28 -6
  207. package/types/cdevhub-ngx-tw-transfer-testing.d.ts +152 -0
  208. package/types/cdevhub-ngx-tw-transfer.d.ts +21 -8
  209. package/types/cdevhub-ngx-tw-tree.d.ts +6 -1
@@ -1,11 +1,7 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, inject, computed, ViewEncapsulation, ChangeDetectionStrategy, Component, signal, Injector, Injectable, makeEnvironmentProviders, Directive, input } from '@angular/core';
3
- import { DialogConfig, CdkDialogContainer, Dialog } from '@angular/cdk/dialog';
4
- import { createBlockScrollStrategy, createNoopScrollStrategy, createRepositionScrollStrategy, createCloseScrollStrategy, createGlobalPositionStrategy } from '@angular/cdk/overlay';
5
- import { ReplaySubject, filter, take, merge, Subject, defer, startWith } from 'rxjs';
6
- import { CdkPortalOutlet } from '@angular/cdk/portal';
7
- import { OverlayContainerCoordinator, mergeOverlayPanelClass, coerceOverlayDuration } from '@cdevhub/ngx-tw/core';
8
- import { tv } from 'tailwind-variants';
2
+ import { InjectionToken, signal, inject, Injector, Injectable, makeEnvironmentProviders, Directive, input, computed } from '@angular/core';
3
+ import { ReplaySubject, Subject, filter, take, merge, defer, startWith } from 'rxjs';
4
+ import { DialogConfig } from '@angular/cdk/dialog';
9
5
  import { ESCAPE, hasModifierKey } from '@angular/cdk/keycodes';
10
6
  import { _IdGenerator } from '@angular/cdk/a11y';
11
7
  import * as i1 from '@angular/cdk/scrolling';
@@ -69,184 +65,42 @@ class SheetConfig extends DialogConfig {
69
65
  restoreFocus = true;
70
66
  }
71
67
  /** Injection token carrying the `data` value passed via {@link SheetConfig.data}. */
72
- const SHEET_DATA = new InjectionToken('SHEET_DATA');
68
+ const TW_SHEET_DATA = new InjectionToken('TW_SHEET_DATA');
73
69
  /** Injection token for application-wide default sheet options. Set via `provideSheet()`. */
74
- const SHEET_DEFAULT_OPTIONS = new InjectionToken('SHEET_DEFAULT_OPTIONS');
75
-
76
- // Sheet uses a `data-[state]` + `data-[side]` driven CSS transition rather than
77
- // the project's `animate.enter`/`animate.leave` keyframes. Same rationale as
78
- // the dialog container (see `dialog-container.ts`):
79
- // 1. The ref owns the open/close lifecycle (state signal, observables) and
80
- // needs runtime-configurable enter/exit durations per `Sheet.open()` call
81
- // — `animate.enter` only accepts a static class name.
82
- // 2. The transform direction depends on `side`, and encoding four pairs of
83
- // keyframe classes (slide-in/out × 4 sides) is noisier than four
84
- // `data-[side=…]` selectors on a single transition rule.
85
- // All other library overlays (popover, menu, tooltip) use animate.enter/leave;
86
- // this divergence is intentional and isolated to the sheet container.
87
- const sheetContainerVariants = tv({
88
- slots: {
89
- host: 'fixed flex flex-col outline-none bg-surface-raised text-fg shadow-md overflow-hidden transition-[transform,opacity] ease-out motion-reduce:transition-none opacity-0 data-[state=open]:opacity-100',
90
- },
91
- variants: {
92
- side: {
93
- right: {
94
- host: 'h-screen right-0 top-0 border-l border-border data-[state=opening]:translate-x-full data-[state=closing]:translate-x-full data-[state=open]:translate-x-0',
95
- },
96
- left: {
97
- host: 'h-screen left-0 top-0 border-r border-border data-[state=opening]:-translate-x-full data-[state=closing]:-translate-x-full data-[state=open]:translate-x-0',
98
- },
99
- top: {
100
- host: 'w-screen left-0 top-0 border-b border-border data-[state=opening]:-translate-y-full data-[state=closing]:-translate-y-full data-[state=open]:translate-y-0',
101
- },
102
- bottom: {
103
- host: 'w-screen left-0 bottom-0 border-t border-border data-[state=opening]:translate-y-full data-[state=closing]:translate-y-full data-[state=open]:translate-y-0',
104
- },
105
- },
106
- size: {
107
- xs: { host: '' },
108
- sm: { host: '' },
109
- md: { host: '' },
110
- lg: { host: '' },
111
- xl: { host: '' },
112
- full: { host: '' },
113
- },
114
- },
115
- // Sheets are axis-aware: `size` controls width on horizontal sides and
116
- // height on vertical sides. Encoded as compound variants so a single
117
- // {side, size} pair resolves to one set of utility classes.
118
- compoundVariants: [
119
- // ── Right-anchored ─────────────────────────────────────────────
120
- { side: 'right', size: 'xs', class: { host: 'w-full max-w-xs' } },
121
- { side: 'right', size: 'sm', class: { host: 'w-full max-w-sm' } },
122
- { side: 'right', size: 'md', class: { host: 'w-full max-w-md' } },
123
- { side: 'right', size: 'lg', class: { host: 'w-full max-w-xl' } },
124
- { side: 'right', size: 'xl', class: { host: 'w-full max-w-2xl' } },
125
- { side: 'right', size: 'full', class: { host: 'w-screen max-w-none' } },
126
- // ── Left-anchored ──────────────────────────────────────────────
127
- { side: 'left', size: 'xs', class: { host: 'w-full max-w-xs' } },
128
- { side: 'left', size: 'sm', class: { host: 'w-full max-w-sm' } },
129
- { side: 'left', size: 'md', class: { host: 'w-full max-w-md' } },
130
- { side: 'left', size: 'lg', class: { host: 'w-full max-w-xl' } },
131
- { side: 'left', size: 'xl', class: { host: 'w-full max-w-2xl' } },
132
- { side: 'left', size: 'full', class: { host: 'w-screen max-w-none' } },
133
- // ── Top-anchored ───────────────────────────────────────────────
134
- { side: 'top', size: 'xs', class: { host: 'h-[20vh]' } },
135
- { side: 'top', size: 'sm', class: { host: 'h-[33vh]' } },
136
- { side: 'top', size: 'md', class: { host: 'h-[50vh]' } },
137
- { side: 'top', size: 'lg', class: { host: 'h-[66vh]' } },
138
- { side: 'top', size: 'xl', class: { host: 'h-[80vh]' } },
139
- { side: 'top', size: 'full', class: { host: 'h-screen' } },
140
- // ── Bottom-anchored ────────────────────────────────────────────
141
- { side: 'bottom', size: 'xs', class: { host: 'h-[20vh]' } },
142
- { side: 'bottom', size: 'sm', class: { host: 'h-[33vh]' } },
143
- { side: 'bottom', size: 'md', class: { host: 'h-[50vh]' } },
144
- { side: 'bottom', size: 'lg', class: { host: 'h-[66vh]' } },
145
- { side: 'bottom', size: 'xl', class: { host: 'h-[80vh]' } },
146
- { side: 'bottom', size: 'full', class: { host: 'h-screen' } },
147
- ],
148
- defaultVariants: { side: 'right', size: 'md' },
149
- }, { twMerge: true });
70
+ const TW_SHEET_DEFAULT_OPTIONS = new InjectionToken('TW_SHEET_DEFAULT_OPTIONS');
150
71
  /**
151
- * Sheet container rendered inside the CDK overlay. Wraps the user-provided
152
- * content in a Tailwind-styled, edge-anchored surface and coordinates slide
153
- * enter/exit transitions with {@link SheetRef}.
154
- *
155
- * The animation state machine, `aria-describedby` queue, and panel-class
156
- * merge are shared with `DialogContainer` via {@link OverlayContainerCoordinator}
157
- * (component-scoped — see `providers: [OverlayContainerCoordinator]`).
158
- *
159
- * @docs-private
72
+ * @deprecated Renamed to {@link TW_SHEET_DATA} for consistency with every other
73
+ * ngx-tw injection token and with `TW_DIALOG_DATA`, its direct counterpart.
74
+ * This is the *same token instance*, not a copy — providing under either name
75
+ * and injecting under the other resolves — so the rename is safe to adopt
76
+ * incrementally. Removed in the next major.
160
77
  */
161
- class SheetContainer extends CdkDialogContainer {
162
- coordinator = inject(OverlayContainerCoordinator);
163
- /** Lifecycle state of the sheet's enter/exit animation. */
164
- state = this.coordinator.state;
165
- /** Emits whenever the animation state transitions. */
166
- animationStateChanged = this.coordinator.animationStateChanged;
167
- /** Resolved enter-animation duration in ms. */
168
- enterAnimationDuration;
169
- /** Resolved exit-animation duration in ms. */
170
- exitAnimationDuration;
171
- sideAttr = computed(() => this._config.side ?? 'right', /* @ts-ignore */
172
- ...(ngDevMode ? [{ debugName: "sideAttr" }] : /* istanbul ignore next */ []));
173
- variants = computed(() => {
174
- const side = this._config.side ?? 'right';
175
- const size = this._config.size ?? 'md';
176
- return sheetContainerVariants({ side, size });
177
- }, /* @ts-ignore */
178
- ...(ngDevMode ? [{ debugName: "variants" }] : /* istanbul ignore next */ []));
179
- hostClasses = computed(() => mergeOverlayPanelClass(this.variants().host(), this._config.panelClass), /* @ts-ignore */
180
- ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
181
- ariaDescribedByAttr = computed(() => this._config.ariaDescribedBy ||
182
- this.coordinator.describedByIds()[0] ||
183
- null, /* @ts-ignore */
184
- ...(ngDevMode ? [{ debugName: "ariaDescribedByAttr" }] : /* istanbul ignore next */ []));
185
- transitionDuration = this.coordinator.transitionDuration;
186
- constructor() {
187
- super();
188
- this.enterAnimationDuration = coerceOverlayDuration(this._config.enterAnimationDuration, 200);
189
- this.exitAnimationDuration = coerceOverlayDuration(this._config.exitAnimationDuration, 160);
190
- this.coordinator.setDurations(this.enterAnimationDuration, this.exitAnimationDuration);
191
- }
192
- _contentAttached() {
193
- super._contentAttached();
194
- this.coordinator.startEnterAnimation();
195
- }
196
- /** Triggered by the sheet ref to play the exit transition before disposing the overlay. */
197
- _startExitAnimation() {
198
- this.coordinator.startExitAnimation();
199
- }
200
- /** Registers a description id for the container's `aria-describedby`. */
201
- _addAriaDescribedBy(id) {
202
- this.coordinator.addAriaDescribedBy(id);
203
- }
204
- /** Removes a previously registered description id. */
205
- _removeAriaDescribedBy(id) {
206
- this.coordinator.removeAriaDescribedBy(id);
207
- }
208
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: SheetContainer, deps: [], target: i0.ɵɵFactoryTarget.Component });
209
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.7", type: SheetContainer, isStandalone: true, selector: "tw-sheet-container", host: { attributes: { "tabindex": "-1" }, properties: { "attr.id": "_config.id || null", "attr.role": "_config.role", "attr.aria-modal": "_config.ariaModal", "attr.aria-labelledby": "_config.ariaLabel ? null : _ariaLabelledByQueue[0]", "attr.aria-label": "_config.ariaLabel", "attr.aria-describedby": "ariaDescribedByAttr()", "attr.data-state": "state()", "attr.data-side": "sideAttr()", "class": "hostClasses()", "style.transition-duration.ms": "transitionDuration()" } }, providers: [OverlayContainerCoordinator], usesInheritance: true, ngImport: i0, template: '<ng-template cdkPortalOutlet />', isInline: true, dependencies: [{ kind: "directive", type: CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
210
- }
211
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: SheetContainer, decorators: [{
212
- type: Component,
213
- args: [{
214
- selector: 'tw-sheet-container',
215
- template: '<ng-template cdkPortalOutlet />',
216
- changeDetection: ChangeDetectionStrategy.OnPush,
217
- encapsulation: ViewEncapsulation.None,
218
- imports: [CdkPortalOutlet],
219
- providers: [OverlayContainerCoordinator],
220
- host: {
221
- tabindex: '-1',
222
- '[attr.id]': '_config.id || null',
223
- '[attr.role]': '_config.role',
224
- '[attr.aria-modal]': '_config.ariaModal',
225
- '[attr.aria-labelledby]': '_config.ariaLabel ? null : _ariaLabelledByQueue[0]',
226
- '[attr.aria-label]': '_config.ariaLabel',
227
- '[attr.aria-describedby]': 'ariaDescribedByAttr()',
228
- '[attr.data-state]': 'state()',
229
- '[attr.data-side]': 'sideAttr()',
230
- '[class]': 'hostClasses()',
231
- '[style.transition-duration.ms]': 'transitionDuration()',
232
- },
233
- }]
234
- }], ctorParameters: () => [] });
78
+ const SHEET_DATA = TW_SHEET_DATA;
79
+ /**
80
+ * @deprecated Renamed to {@link TW_SHEET_DEFAULT_OPTIONS} for consistency with
81
+ * every other ngx-tw injection token — and with `TW_DIALOG_DEFAULT_OPTIONS`,
82
+ * its direct counterpart. This is the *same token instance*, not a copy —
83
+ * providing under either name and injecting under the other resolves — so the
84
+ * rename is safe to adopt incrementally. Removed in the next major.
85
+ */
86
+ const SHEET_DEFAULT_OPTIONS = TW_SHEET_DEFAULT_OPTIONS;
235
87
 
236
88
  /**
237
89
  * Reference to a sheet opened via {@link Sheet.open}. Drives the sheet
238
90
  * lifecycle (close, state, observables) and forwards useful overlay streams.
91
+ *
92
+ * The ref is returned **synchronously** from `open()`, but the sheet's render
93
+ * layer (`@angular/cdk/dialog` + the Tailwind container) is loaded through a
94
+ * dynamic `import()`. The ref therefore starts *detached*: `id`, `state`,
95
+ * `close()`, the lifecycle observables, and panel mutations all work
96
+ * immediately (mutations are buffered and replayed on attach), but the rendered
97
+ * component instance does not exist yet — read it via {@link whenComponentReady}
98
+ * instead of a synchronous `componentInstance` field.
239
99
  */
240
100
  class SheetRef {
241
- cdkRef;
242
101
  config;
243
- containerInstance;
244
- /** Unique ID of the sheet. */
102
+ /** Unique ID of the sheet. Generated eagerly by the service, so it is valid the instant `open()` returns. */
245
103
  id;
246
- /** Instance of the component rendered inside the sheet, or `null` for template sheets. */
247
- componentInstance = null;
248
- /** `ComponentRef` of the content component, or `null` for template sheets. */
249
- componentRef = null;
250
104
  /** Current lifecycle state. Reactively readable. */
251
105
  state;
252
106
  /** When `true`, close-via-escape AND close-via-backdrop are both disabled. */
@@ -260,19 +114,56 @@ class SheetRef {
260
114
  afterOpenedSubject = new ReplaySubject(1);
261
115
  beforeClosedSubject = new ReplaySubject(1);
262
116
  afterClosedSubject = new ReplaySubject(1);
117
+ // Facade-owned pass-throughs for the raw overlay streams, so a consumer that
118
+ // subscribes before the render chunk attaches still receives events once it
119
+ // does — the pre-deferral behaviour when `open()` wrapped a live `cdkRef`.
120
+ backdropClickSubject = new Subject();
121
+ keydownEventsSubject = new Subject();
122
+ cdkRef = null;
123
+ container = null;
124
+ componentInstanceValue = null;
125
+ componentRefValue = null;
126
+ resolveComponentReady;
127
+ componentReadyPromise = new Promise((resolve) => {
128
+ this.resolveComponentReady = resolve;
129
+ });
130
+ // Buffered mutations issued before the render chunk attached the CDK backend.
131
+ pendingPanelAdds = [];
132
+ pendingPanelRemoves = [];
263
133
  pendingResult;
264
134
  closeFocusOrigin;
265
- constructor(cdkRef, config, containerInstance) {
266
- this.cdkRef = cdkRef;
135
+ constructor(id, config) {
267
136
  this.config = config;
268
- this.containerInstance = containerInstance;
269
- this.id = cdkRef.id;
137
+ this.id = id;
270
138
  this.disableClose = config.disableClose;
271
139
  this.closeOnEscape = config.closeOnEscape;
272
140
  this.closeOnBackdropClick = config.closeOnBackdropClick;
273
141
  this.state = this.stateSignal.asReadonly();
142
+ }
143
+ /** The Tailwind container instance, or `null` until the sheet has attached. */
144
+ get containerInstance() {
145
+ return this.container;
146
+ }
147
+ /**
148
+ * @internal Wire this facade to its CDK backend. Called from the sheet
149
+ * renderer **inside** `cdkDialog.open()`'s `providers` callback — the same
150
+ * point the constructor ran before deferral — so subscriptions to
151
+ * `animationStateChanged` are in place before the container emits `'open'`.
152
+ */
153
+ _attach(cdkRef, container) {
154
+ this.cdkRef = cdkRef;
155
+ this.container = container;
156
+ // Forward the raw overlay streams into the facade pass-throughs.
157
+ cdkRef.backdropClick.subscribe(this.backdropClickSubject);
158
+ cdkRef.keydownEvents.subscribe(this.keydownEventsSubject);
274
159
  cdkRef.addPanelClass('tw-sheet-panel');
275
- const animationChanges = containerInstance.animationStateChanged;
160
+ for (const cls of this.pendingPanelAdds)
161
+ cdkRef.addPanelClass(cls);
162
+ for (const cls of this.pendingPanelRemoves)
163
+ cdkRef.removePanelClass(cls);
164
+ this.pendingPanelAdds.length = 0;
165
+ this.pendingPanelRemoves.length = 0;
166
+ const animationChanges = container.animationStateChanged;
276
167
  animationChanges
277
168
  .pipe(filter((event) => event.state === 'open'), take(1))
278
169
  .subscribe(() => {
@@ -301,6 +192,38 @@ class SheetRef {
301
192
  this.closeWithOrigin(event.type === 'keydown' ? 'keyboard' : 'mouse');
302
193
  });
303
194
  }
195
+ /** @internal Record the rendered component after `cdkDialog.open()` returns. */
196
+ _setComponent(instance, ref) {
197
+ this.componentInstanceValue = instance;
198
+ this.componentRefValue = ref;
199
+ this.resolveComponentReady(instance);
200
+ }
201
+ /**
202
+ * Resolves with the rendered content-component instance once the sheet's
203
+ * render chunk has loaded and attached. Resolves `null` for template sheets,
204
+ * and for a sheet closed before it ever opened.
205
+ *
206
+ * Replaces the former synchronous `componentInstance` field, which cannot be
207
+ * populated before the deferred render chunk lands.
208
+ *
209
+ * @example
210
+ * ```ts
211
+ * const ref = sheet.open(FilterSheet);
212
+ * const filters = await ref.whenComponentReady();
213
+ * filters?.reset();
214
+ * ```
215
+ */
216
+ whenComponentReady() {
217
+ return this.componentReadyPromise;
218
+ }
219
+ /** The rendered component instance, or `null` if not yet attached / a template sheet. Prefer {@link whenComponentReady}. */
220
+ get componentInstance() {
221
+ return this.componentInstanceValue;
222
+ }
223
+ /** The rendered `ComponentRef`, or `null` if not yet attached / a template sheet. */
224
+ get componentRef() {
225
+ return this.componentRefValue;
226
+ }
304
227
  /**
305
228
  * Closes the sheet. The exit slide animation runs before the overlay is disposed.
306
229
  * @param result Value forwarded to `afterClosed()` subscribers.
@@ -320,22 +243,32 @@ class SheetRef {
320
243
  afterClosed() {
321
244
  return this.afterClosedSubject.asObservable();
322
245
  }
323
- /** Backdrop click stream (emits even when `closeOnBackdropClick` / `disableClose` is set). */
246
+ /** Backdrop click stream (emits even when `closeOnBackdropClick` / `disableClose` is set). Buffered — a subscription made before the sheet attaches receives events once it does. */
324
247
  backdropClick() {
325
- return this.cdkRef.backdropClick;
248
+ return this.backdropClickSubject.asObservable();
326
249
  }
327
- /** Keydown event stream for the overlay. */
250
+ /** Keydown event stream for the overlay. Buffered — a subscription made before the sheet attaches receives events once it does. */
328
251
  keydownEvents() {
329
- return this.cdkRef.keydownEvents;
252
+ return this.keydownEventsSubject.asObservable();
330
253
  }
331
- /** Adds CSS classes to the overlay panel. */
254
+ /** Adds CSS classes to the overlay panel. Buffered until attach. */
332
255
  addPanelClass(classes) {
333
- this.cdkRef.addPanelClass(classes);
256
+ if (this.cdkRef) {
257
+ this.cdkRef.addPanelClass(classes);
258
+ }
259
+ else {
260
+ this.pendingPanelAdds.push(...(Array.isArray(classes) ? classes : [classes]));
261
+ }
334
262
  return this;
335
263
  }
336
- /** Removes CSS classes from the overlay panel. */
264
+ /** Removes CSS classes from the overlay panel. Buffered until attach. */
337
265
  removePanelClass(classes) {
338
- this.cdkRef.removePanelClass(classes);
266
+ if (this.cdkRef) {
267
+ this.cdkRef.removePanelClass(classes);
268
+ }
269
+ else {
270
+ this.pendingPanelRemoves.push(...(Array.isArray(classes) ? classes : [classes]));
271
+ }
339
272
  return this;
340
273
  }
341
274
  closeWithOrigin(origin, result) {
@@ -343,7 +276,7 @@ class SheetRef {
343
276
  return;
344
277
  const predicate = this.config.closePredicate;
345
278
  if (predicate &&
346
- !predicate(result, this.config, this.componentInstance)) {
279
+ !predicate(result, this.config, this.componentInstanceValue)) {
347
280
  return;
348
281
  }
349
282
  this.pendingResult = result;
@@ -351,8 +284,15 @@ class SheetRef {
351
284
  this.stateSignal.set('closing');
352
285
  this.beforeClosedSubject.next(result);
353
286
  this.beforeClosedSubject.complete();
287
+ if (!this.cdkRef) {
288
+ // Closed before the render chunk attached: the overlay was never created,
289
+ // so there is nothing to animate or dispose. Synthesize the closed state
290
+ // and let the service skip opening entirely (it checks state()).
291
+ this.finishClose();
292
+ return;
293
+ }
354
294
  this.cdkRef.overlayRef.detachBackdrop();
355
- this.containerInstance._startExitAnimation();
295
+ this.container._startExitAnimation();
356
296
  }
357
297
  finishClose() {
358
298
  if (this.stateSignal() === 'closed')
@@ -360,26 +300,42 @@ class SheetRef {
360
300
  this.stateSignal.set('closed');
361
301
  this.afterClosedSubject.next(this.pendingResult);
362
302
  this.afterClosedSubject.complete();
363
- if (this.cdkRef.containerInstance) {
303
+ // Idempotent — a no-op if _setComponent already resolved with an instance.
304
+ this.resolveComponentReady(null);
305
+ this.backdropClickSubject.complete();
306
+ this.keydownEventsSubject.complete();
307
+ if (this.cdkRef?.containerInstance) {
364
308
  this.cdkRef.close(this.pendingResult, { focusOrigin: this.closeFocusOrigin });
365
309
  }
366
- this.componentInstance = null;
310
+ this.componentInstanceValue = null;
367
311
  }
368
312
  }
369
313
 
314
+ let nextSheetId = 0;
315
+ function generateSheetId() {
316
+ return `tw-sheet-${++nextSheetId}`;
317
+ }
370
318
  /**
371
319
  * Opens edge-anchored sheet (drawer) overlays. Composes `@angular/cdk/dialog`
372
320
  * for focus trapping, portals, and overlay plumbing — adds a `GlobalPositionStrategy`
373
321
  * pinned to the requested viewport edge, a Tailwind container with axis-aware
374
322
  * sizing, slide enter/exit animations, and split close-behavior flags.
375
323
  *
324
+ * The rendering layer (`@angular/cdk/dialog` + the Tailwind container) is loaded
325
+ * through a dynamic `import()` on the first `open()` call, so merely registering
326
+ * this service costs nothing in the initial bundle. `open()` still returns its
327
+ * {@link SheetRef} synchronously — the sheet is rendered once the chunk lands.
328
+ * Read the rendered component via {@link SheetRef.whenComponentReady}.
329
+ *
376
330
  * Not `providedIn: 'root'` — register it via {@link provideSheet}.
377
331
  */
378
332
  class Sheet {
379
- cdkDialog = inject(Dialog);
380
333
  injector = inject(Injector);
381
- defaultOptions = inject(SHEET_DEFAULT_OPTIONS, { optional: true }) ?? {};
334
+ defaultOptions = inject(TW_SHEET_DEFAULT_OPTIONS, { optional: true }) ?? {};
382
335
  parentSheet = inject(Sheet, { optional: true, skipSelf: true });
336
+ /** Cached renderer chunk import — kicked off on the first `open()`. */
337
+ rendererPromise = null;
338
+ destroyed = false;
383
339
  openSheetsAtThisLevel = signal([], /* @ts-ignore */
384
340
  ...(ngDevMode ? [{ debugName: "openSheetsAtThisLevel" }] : /* istanbul ignore next */ []));
385
341
  afterOpenedSubject = new Subject();
@@ -403,61 +359,25 @@ class Sheet {
403
359
  * Opens a sheet using the given component or template.
404
360
  * @param content Component class or `TemplateRef`.
405
361
  * @param config Options merged over the application defaults.
406
- * @returns Reference controlling the opened sheet.
362
+ * @returns Reference controlling the opened sheet, returned synchronously.
407
363
  */
408
364
  open(content, config) {
409
365
  const merged = this.resolveConfig(config);
410
- let sheetRef;
411
- const cdkRef = this.cdkDialog.open(content, {
412
- id: merged.id,
413
- role: merged.role,
414
- data: merged.data,
415
- panelClass: merged.panelClass,
416
- backdropClass: merged.backdropClass || 'tw-sheet-backdrop',
417
- hasBackdrop: merged.hasBackdrop,
418
- // Sheet sizing happens on the container element (axis-aware width/height
419
- // utilities). The overlay pane itself is the full-edge bounding box.
420
- direction: merged.direction,
421
- ariaDescribedBy: merged.ariaDescribedBy,
422
- ariaLabelledBy: merged.ariaLabelledBy,
423
- ariaLabel: merged.ariaLabel,
424
- ariaModal: merged.ariaModal,
425
- autoFocus: merged.autoFocus,
426
- restoreFocus: merged.restoreFocus,
427
- scrollStrategy: merged.scrollStrategy ?? this.resolveScrollStrategy(merged.scrollBehavior),
428
- positionStrategy: merged.positionStrategy ?? this.resolvePositionStrategy(merged.side ?? 'right'),
429
- closeOnNavigation: merged.closeOnNavigation,
430
- viewContainerRef: merged.viewContainerRef,
431
- injector: merged.injector,
432
- // We handle close/Escape/backdrop ourselves so we can run the exit slide animation.
433
- disableClose: true,
434
- closeOnOverlayDetachments: false,
435
- container: {
436
- type: SheetContainer,
437
- providers: () => [
438
- { provide: SheetConfig, useValue: merged },
439
- { provide: DialogConfig, useValue: merged },
440
- ],
441
- },
442
- providers: (_cdkRef, _cdkConfig, container) => {
443
- sheetRef = new SheetRef(_cdkRef, merged, container);
444
- const providers = [
445
- { provide: SheetRef, useValue: sheetRef },
446
- { provide: SHEET_DATA, useValue: merged.data ?? null },
447
- ];
448
- if (Array.isArray(merged.providers))
449
- providers.push(...merged.providers);
450
- return providers;
451
- },
452
- });
453
- // After CDK attaches the component, copy references onto our ref.
454
- sheetRef.componentRef = cdkRef.componentRef;
455
- sheetRef.componentInstance = cdkRef.componentInstance;
366
+ const id = merged.id ?? generateSheetId();
367
+ merged.id = id;
368
+ // Enforce id uniqueness eagerly. CDK throws this synchronously from
369
+ // `open()`; since our CDK open is now deferred, replicate the check here so
370
+ // the error still surfaces at the call site rather than in a later tick.
371
+ if (this.getSheetById(id)) {
372
+ throw new Error(`Sheet with id "${id}" exists already. The sheet id must be unique.`);
373
+ }
374
+ const sheetRef = new SheetRef(id, merged);
456
375
  const scope = this.parentSheet ?? this;
457
376
  scope.registerOpen(sheetRef);
458
377
  sheetRef.afterClosed().subscribe(() => {
459
378
  scope.unregister(sheetRef);
460
379
  });
380
+ void this.renderWhenReady(content, merged, sheetRef);
461
381
  return sheetRef;
462
382
  }
463
383
  /** Closes every open sheet managed by this service (and child services). */
@@ -471,12 +391,42 @@ class Sheet {
471
391
  return this.openSheets().find((sheet) => sheet.id === id);
472
392
  }
473
393
  ngOnDestroy() {
394
+ this.destroyed = true;
474
395
  const sheets = [...this.openSheetsAtThisLevel()];
475
396
  for (let i = sheets.length - 1; i >= 0; i--)
476
397
  sheets[i].close();
477
398
  this.afterOpenedSubject.complete();
478
399
  this.afterAllClosedSubject.complete();
479
400
  }
401
+ /**
402
+ * @internal Resolves once the renderer chunk has loaded. Exposed for tests,
403
+ * which must await the dynamic import before asserting on rendered DOM.
404
+ */
405
+ async _whenRendered() {
406
+ await this.loadRenderer();
407
+ await Promise.resolve();
408
+ }
409
+ /**
410
+ * Render a sheet once the renderer chunk has loaded. The ref was already
411
+ * returned to the caller, so it may have been closed (or the service
412
+ * destroyed) while the import was in flight — both skip the actual open.
413
+ */
414
+ async renderWhenReady(content, merged, sheetRef) {
415
+ const openRendered = await this.loadRenderer();
416
+ if (!openRendered || this.destroyed)
417
+ return;
418
+ // Closed before the chunk landed — the facade already synthesized its
419
+ // closed state; never create the overlay.
420
+ if (sheetRef.state() === 'closed')
421
+ return;
422
+ openRendered(this.injector, content, merged, sheetRef);
423
+ }
424
+ loadRenderer() {
425
+ if (!this.rendererPromise) {
426
+ this.rendererPromise = import('./cdevhub-ngx-tw-sheet-sheet-renderer-CqVJwgmp.mjs').then(({ openRenderedSheet }) => this.destroyed ? null : openRenderedSheet);
427
+ }
428
+ return this.rendererPromise;
429
+ }
480
430
  registerOpen(ref) {
481
431
  if (this.parentSheet) {
482
432
  this.parentSheet.registerOpen(ref);
@@ -507,33 +457,6 @@ class Sheet {
507
457
  Object.assign(merged, this.defaultOptions, config);
508
458
  return merged;
509
459
  }
510
- resolveScrollStrategy(strategy) {
511
- switch (strategy) {
512
- case 'close':
513
- return createCloseScrollStrategy(this.injector);
514
- case 'reposition':
515
- return createRepositionScrollStrategy(this.injector);
516
- case 'noop':
517
- return createNoopScrollStrategy();
518
- case 'block':
519
- default:
520
- return createBlockScrollStrategy(this.injector);
521
- }
522
- }
523
- resolvePositionStrategy(side) {
524
- const strategy = createGlobalPositionStrategy(this.injector);
525
- switch (side) {
526
- case 'left':
527
- return strategy.top('0').left('0').bottom('0');
528
- case 'top':
529
- return strategy.top('0').left('0').right('0');
530
- case 'bottom':
531
- return strategy.bottom('0').left('0').right('0');
532
- case 'right':
533
- default:
534
- return strategy.top('0').right('0').bottom('0');
535
- }
536
- }
537
460
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: Sheet, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
538
461
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: Sheet });
539
462
  }
@@ -552,7 +475,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
552
475
  function provideSheet(defaultOptions) {
553
476
  const providers = [Sheet];
554
477
  if (defaultOptions) {
555
- providers.push({ provide: SHEET_DEFAULT_OPTIONS, useValue: defaultOptions });
478
+ providers.push({ provide: TW_SHEET_DEFAULT_OPTIONS, useValue: defaultOptions });
556
479
  }
557
480
  return makeEnvironmentProviders(providers);
558
481
  }
@@ -620,21 +543,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
620
543
  class SheetTitleDirective {
621
544
  generatedId = inject(_IdGenerator).getId('tw-sheet-title-');
622
545
  sheetRef = inject(SheetRef, { optional: true });
623
- // Ancestor-DI fallback for the rare case where `SheetRef` is not in the
624
546
  // directive's injector chain (e.g. heavily nested template portals). The
625
547
  // container ALWAYS resolves via element-injector traversal because the
626
548
  // directive lives inside `<tw-sheet-container>`'s DOM tree.
627
- container = inject(SheetContainer, { optional: true, skipSelf: true });
628
549
  /** Custom id for the title element. Defaults to a generated unique id. */
629
550
  id = input(this.generatedId, /* @ts-ignore */
630
551
  ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
631
552
  ngOnInit() {
632
- const containerInstance = this.sheetRef?.containerInstance ?? this.container;
553
+ const containerInstance = this.sheetRef?.containerInstance;
633
554
  if (containerInstance)
634
555
  containerInstance._addAriaLabelledBy(this.id());
635
556
  }
636
557
  ngOnDestroy() {
637
- const containerInstance = this.sheetRef?.containerInstance ?? this.container;
558
+ const containerInstance = this.sheetRef?.containerInstance;
638
559
  if (containerInstance)
639
560
  containerInstance._removeAriaLabelledBy(this.id());
640
561
  }
@@ -673,18 +594,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
673
594
  class SheetDescriptionDirective {
674
595
  generatedId = inject(_IdGenerator).getId('tw-sheet-description-');
675
596
  sheetRef = inject(SheetRef, { optional: true });
676
- // Ancestor-DI fallback — see SheetTitleDirective.
677
- container = inject(SheetContainer, { optional: true, skipSelf: true });
678
597
  /** Custom id for the description element. Defaults to a generated unique id. */
679
598
  id = input(this.generatedId, /* @ts-ignore */
680
599
  ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
681
600
  ngOnInit() {
682
- const containerInstance = this.sheetRef?.containerInstance ?? this.container;
601
+ const containerInstance = this.sheetRef?.containerInstance;
683
602
  if (containerInstance)
684
603
  containerInstance._addAriaDescribedBy(this.id());
685
604
  }
686
605
  ngOnDestroy() {
687
- const containerInstance = this.sheetRef?.containerInstance ?? this.container;
606
+ const containerInstance = this.sheetRef?.containerInstance;
688
607
  if (containerInstance)
689
608
  containerInstance._removeAriaDescribedBy(this.id());
690
609
  }
@@ -750,7 +669,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
750
669
  * `[twSheetClose]` value to pass a result to `afterClosed()` subscribers.
751
670
  */
752
671
  class SheetCloseDirective {
753
- /** Value passed to `afterClosed()` when the button is clicked. */
672
+ /** Value passed to `afterClosed()` when the button is clicked. Defaults to `undefined`. */
754
673
  twSheetClose = input(undefined, /* @ts-ignore */
755
674
  ...(ngDevMode ? [{ debugName: "twSheetClose" }] : /* istanbul ignore next */ []));
756
675
  /** Native button `type`. Defaults to `'button'` to avoid accidental form submission. */
@@ -778,5 +697,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
778
697
  * Generated bundle index. Do not edit.
779
698
  */
780
699
 
781
- export { SHEET_DATA, SHEET_DEFAULT_OPTIONS, Sheet, SheetActionsDirective, SheetCloseDirective, SheetConfig, SheetContainer, SheetContentDirective, SheetDescriptionDirective, SheetHeaderDirective, SheetIconDirective, SheetRef, SheetSubtitleDirective, SheetTitleDirective, provideSheet };
700
+ export { SHEET_DATA, SHEET_DEFAULT_OPTIONS, Sheet, SheetActionsDirective, SheetCloseDirective, SheetConfig, SheetContentDirective, SheetDescriptionDirective, SheetHeaderDirective, SheetIconDirective, SheetRef, SheetSubtitleDirective, SheetTitleDirective, TW_SHEET_DATA, TW_SHEET_DEFAULT_OPTIONS, provideSheet };
782
701
  //# sourceMappingURL=cdevhub-ngx-tw-sheet.mjs.map