@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 +1 @@
1
- {"version":3,"file":"cdevhub-ngx-tw-dialog.mjs","sources":["../../../projects/ngx-tw/dialog/dialog-config.ts","../../../projects/ngx-tw/dialog/dialog-container.ts","../../../projects/ngx-tw/dialog/dialog-ref.ts","../../../projects/ngx-tw/dialog/dialog.ts","../../../projects/ngx-tw/dialog/dialog-content.ts","../../../projects/ngx-tw/dialog/cdevhub-ngx-tw-dialog.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport {\n type AutoFocusTarget,\n DialogConfig as CdkDialogConfig,\n type DialogRole,\n type RestoreFocusValue,\n} from '@angular/cdk/dialog';\n\n/** Preset sizes mapped to width constraints for the dialog panel. */\nexport type TwDialogSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'fullscreen';\n\n/** ARIA role of the dialog element. Use `'alertdialog'` for destructive confirmation prompts. */\nexport type TwDialogRole = DialogRole;\n\n/** Where to move focus when the dialog opens. */\nexport type TwDialogAutoFocus = AutoFocusTarget | string | boolean;\n\n/** How to restore focus on close. `true` restores to the previously focused element; a selector or element targets a specific node. */\nexport type TwDialogRestoreFocus = RestoreFocusValue;\n\n/** Scroll behavior for content underneath the dialog. */\nexport type TwDialogScrollStrategy = 'block' | 'close' | 'reposition' | 'noop';\n\n/**\n * Configuration for opening a dialog with {@link TwDialog.open}.\n *\n * Mirrors the shape of `@angular/cdk/dialog`'s `DialogConfig` with additional\n * tailwind-focused options (`size`, `enterAnimationDuration`, etc.).\n */\nexport class TwDialogConfig<D = unknown, R = unknown> extends CdkDialogConfig<D, R> {\n /** Preset size for the dialog panel. Ignored when `width`/`maxWidth` are provided. Defaults to `'md'`. */\n size?: TwDialogSize = 'md';\n\n /** Duration of the open animation in ms. Defaults to `150`. Use `0` to disable. */\n enterAnimationDuration?: number = 150;\n\n /**\n * Duration of the close animation in ms. Defaults to `120`. Use `0` to disable.\n * Asymmetric with `enterAnimationDuration` by design: the close transition is\n * slightly faster so the dialog feels dismissive rather than reluctant.\n */\n exitAnimationDuration?: number = 120;\n\n /** Scroll strategy preset applied when `scrollStrategy` isn't set. Defaults to `'block'`. */\n scrollBehavior?: TwDialogScrollStrategy = 'block';\n\n /** Maximum width. Number values are treated as pixels. Defaults to `'calc(100vw - 32px)'`. */\n override maxWidth?: number | string = 'calc(100vw - 32px)';\n\n /**\n * Whether the dialog is modal — sets `aria-modal` on the container.\n * Defaults to `true`: a `role=\"dialog\"` opened over the page is modal by\n * default and the rest of the document is inert while it is open. Set to\n * `false` only for non-modal surfaces (rare; consider `popover` instead).\n */\n override ariaModal?: boolean = true;\n\n /** Whether Escape and backdrop clicks are blocked. Defaults to `false`. */\n override disableClose?: boolean = false;\n\n /** Where to move focus when the dialog opens. Defaults to `'first-tabbable'`. */\n override autoFocus?: TwDialogAutoFocus = 'first-tabbable';\n\n /** Whether to restore focus to the previously focused element after close. Defaults to `true`. */\n override restoreFocus?: TwDialogRestoreFocus = true;\n\n /** Whether the dialog renders a backdrop. Defaults to `true`. */\n override hasBackdrop?: boolean = true;\n\n /** Whether navigation (e.g. router) closes the dialog. Defaults to `true`. */\n override closeOnNavigation?: boolean = true;\n}\n\n/** Injection token carrying the `data` value passed via {@link TwDialogConfig.data}. */\nexport const TW_DIALOG_DATA = new InjectionToken<unknown>('TW_DIALOG_DATA');\n\n/** Injection token for application-wide default dialog options. Set via `provideTwDialog()`. */\nexport const TW_DIALOG_DEFAULT_OPTIONS = new InjectionToken<Partial<TwDialogConfig>>(\n 'TW_DIALOG_DEFAULT_OPTIONS',\n);\n","import {\n ChangeDetectionStrategy,\n Component,\n type EventEmitter,\n inject,\n type Signal,\n ViewEncapsulation,\n computed,\n} from '@angular/core';\nimport { CdkDialogContainer } from '@angular/cdk/dialog';\nimport { CdkPortalOutlet } from '@angular/cdk/portal';\nimport {\n coerceOverlayDuration,\n mergeOverlayPanelClass,\n OverlayContainerCoordinator,\n type OverlayContainerAnimationEvent,\n type OverlayContainerState,\n} from '@cdevhub/ngx-tw/core';\nimport { tv } from 'tailwind-variants';\nimport { type TwDialogConfig } from './dialog-config';\n\n/** Lifecycle states a dialog passes through. */\nexport type DialogState = OverlayContainerState;\n\n/** Event emitted when the dialog's animation state transitions. */\nexport type DialogAnimationEvent = OverlayContainerAnimationEvent;\n\n// Dialog uses a `data-[state]` driven CSS transition rather than the project's\n// `animate.enter`/`animate.leave` keyframes. Justification:\n// 1. The ref owns the open/close lifecycle (state signal, observables) and\n// needs runtime-configurable enter/exit durations per `TwDialog.open()`\n// call — `animate.enter` only accepts a static class name.\n// 2. The container drives the same CSS variables (opacity + scale) for both\n// transitions, so a single `transition-[opacity,transform]` rule with a\n// data-state attribute is simpler than two keyframe declarations.\n// All other library overlays (popover, menu, tooltip) use animate.enter/leave;\n// this divergence is intentional and isolated to the dialog container.\nconst dialogContainerVariants = tv(\n {\n slots: {\n host: 'relative flex flex-col outline-none bg-surface-raised text-fg rounded-lg shadow-md border border-border overflow-hidden transition-[opacity,transform] ease-out motion-reduce:transition-none opacity-0 scale-95 data-[state=open]:opacity-100 data-[state=open]:scale-100 data-[state=closing]:opacity-0 data-[state=closing]:scale-95',\n },\n variants: {\n size: {\n xs: { host: 'w-full max-w-sm max-h-[85vh]' },\n sm: { host: 'w-full max-w-md max-h-[85vh]' },\n md: { host: 'w-full max-w-lg max-h-[85vh]' },\n lg: { host: 'w-full max-w-2xl max-h-[85vh]' },\n xl: { host: 'w-full max-w-4xl max-h-[85vh]' },\n fullscreen: {\n host: 'w-screen h-screen max-w-none max-h-none rounded-none border-0',\n },\n },\n },\n defaultVariants: { size: 'md' },\n },\n { twMerge: true },\n);\n\n/**\n * Dialog container rendered inside the CDK overlay. Wraps the user-provided\n * content in a Tailwind-styled surface and coordinates enter/exit transitions\n * with {@link TwDialogRef}.\n *\n * The animation state machine, `aria-describedby` queue, and panel-class\n * merge are shared with `SheetContainer` via {@link OverlayContainerCoordinator}\n * (component-scoped — see `providers: [OverlayContainerCoordinator]`).\n *\n * @docs-private\n */\n@Component({\n selector: 'tw-dialog-container',\n template: '<ng-template cdkPortalOutlet />',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [CdkPortalOutlet],\n providers: [OverlayContainerCoordinator],\n host: {\n tabindex: '-1',\n '[attr.id]': '_config.id || null',\n '[attr.role]': '_config.role',\n '[attr.aria-modal]': '_config.ariaModal',\n '[attr.aria-labelledby]': '_config.ariaLabel ? null : _ariaLabelledByQueue[0]',\n '[attr.aria-label]': '_config.ariaLabel',\n '[attr.aria-describedby]': 'ariaDescribedByAttr()',\n '[attr.data-state]': 'state()',\n '[class]': 'hostClasses()',\n '[style.transition-duration.ms]': 'transitionDuration()',\n },\n})\nexport class DialogContainer extends CdkDialogContainer<TwDialogConfig> {\n private readonly coordinator = inject(OverlayContainerCoordinator);\n\n /** Lifecycle state of the dialog's enter/exit animation. */\n readonly state: Signal<DialogState> = this.coordinator.state;\n\n /** Emits whenever the animation state transitions. */\n readonly animationStateChanged: EventEmitter<DialogAnimationEvent> =\n this.coordinator.animationStateChanged;\n\n /** Resolved enter-animation duration in ms. */\n readonly enterAnimationDuration: number;\n /** Resolved exit-animation duration in ms. */\n readonly exitAnimationDuration: number;\n\n private readonly sizeVariant = computed(() => {\n const size = this._config.size ?? 'md';\n return dialogContainerVariants({ size });\n });\n\n protected readonly hostClasses = computed(() =>\n mergeOverlayPanelClass(this.sizeVariant().host(), this._config.panelClass),\n );\n\n protected readonly ariaDescribedByAttr = computed(\n () =>\n this._config.ariaDescribedBy ||\n this.coordinator.describedByIds()[0] ||\n null,\n );\n\n protected readonly transitionDuration = this.coordinator.transitionDuration;\n\n constructor() {\n super();\n this.enterAnimationDuration = coerceOverlayDuration(this._config.enterAnimationDuration, 150);\n this.exitAnimationDuration = coerceOverlayDuration(this._config.exitAnimationDuration, 120);\n this.coordinator.setDurations(this.enterAnimationDuration, this.exitAnimationDuration);\n }\n\n protected override _contentAttached(): void {\n super._contentAttached();\n this.coordinator.startEnterAnimation();\n }\n\n /** Triggered by the dialog ref to play the exit transition before disposing the overlay. */\n _startExitAnimation(): void {\n this.coordinator.startExitAnimation();\n }\n\n /** Registers a description id for the container's `aria-describedby`. */\n _addAriaDescribedBy(id: string): void {\n this.coordinator.addAriaDescribedBy(id);\n }\n\n /** Removes a previously registered description id. */\n _removeAriaDescribedBy(id: string): void {\n this.coordinator.removeAriaDescribedBy(id);\n }\n}\n","import { type ComponentRef, signal, type Signal } from '@angular/core';\nimport { type DialogRef as CdkDialogRef } from '@angular/cdk/dialog';\nimport { ESCAPE, hasModifierKey } from '@angular/cdk/keycodes';\nimport { filter, merge, type Observable, ReplaySubject, take } from 'rxjs';\nimport type { FocusOrigin } from '@angular/cdk/a11y';\nimport type { TwDialogConfig } from './dialog-config';\nimport type { DialogContainer, DialogState } from './dialog-container';\n\n/**\n * Reference to a dialog opened via {@link TwDialog.open}. Drives the dialog\n * lifecycle (close, state, observables) and forwards useful overlay streams.\n */\nexport class TwDialogRef<R = unknown, C = unknown> {\n /** Unique ID of the dialog. */\n readonly id: string;\n\n /** Instance of the component rendered inside the dialog, or `null` for template dialogs. */\n componentInstance: C | null = null;\n\n /** `ComponentRef` of the content component, or `null` for template dialogs. */\n readonly componentRef: ComponentRef<C> | null = null;\n\n /** Current lifecycle state. Reactively readable. */\n readonly state: Signal<DialogState>;\n\n /** When `true`, close-via-escape and close-via-backdrop are disabled. */\n disableClose: boolean | undefined;\n\n private readonly stateSignal = signal<DialogState>('opening');\n private readonly afterOpenedSubject = new ReplaySubject<void>(1);\n private readonly beforeClosedSubject = new ReplaySubject<R | undefined>(1);\n private readonly afterClosedSubject = new ReplaySubject<R | undefined>(1);\n\n private pendingResult: R | undefined;\n private closeFocusOrigin: FocusOrigin | undefined;\n\n constructor(\n private readonly cdkRef: CdkDialogRef<R, C>,\n readonly config: TwDialogConfig<unknown, R>,\n readonly containerInstance: DialogContainer,\n ) {\n this.id = cdkRef.id;\n this.disableClose = config.disableClose;\n this.state = this.stateSignal.asReadonly();\n\n cdkRef.addPanelClass('tw-dialog-panel');\n\n const animationChanges = containerInstance.animationStateChanged;\n\n animationChanges\n .pipe(\n filter((event) => event.state === 'open'),\n take(1),\n )\n .subscribe(() => {\n this.stateSignal.set('open');\n this.afterOpenedSubject.next();\n this.afterOpenedSubject.complete();\n });\n\n // The container owns the exit-animation fallback timer (see\n // ANIMATION_FALLBACK_PADDING in dialog-container.ts), so we trust its\n // `closed` emission and run finishClose exactly once from here.\n animationChanges\n .pipe(\n filter((event) => event.state === 'closed'),\n take(1),\n )\n .subscribe(() => this.finishClose());\n\n cdkRef.overlayRef.detachments().subscribe(() => {\n if (this.stateSignal() !== 'closed') {\n this.beforeClosedSubject.next(this.pendingResult);\n this.beforeClosedSubject.complete();\n this.finishClose();\n }\n });\n\n merge(\n cdkRef.backdropClick,\n cdkRef.keydownEvents.pipe(\n filter(\n (event) => event.keyCode === ESCAPE && !this.disableClose && !hasModifierKey(event),\n ),\n ),\n ).subscribe((event) => {\n if (this.disableClose) return;\n event.preventDefault();\n this.closeWithOrigin(event.type === 'keydown' ? 'keyboard' : 'mouse');\n });\n }\n\n /**\n * Closes the dialog. The exit animation runs before the overlay is disposed.\n * @param result Value forwarded to `afterClosed()` subscribers.\n */\n close(result?: R): void {\n this.closeWithOrigin('program', result);\n }\n\n /** Observable that emits once after the enter animation finishes. */\n afterOpened(): Observable<void> {\n return this.afterOpenedSubject.asObservable();\n }\n\n /** Observable that emits once when the close animation starts. */\n beforeClosed(): Observable<R | undefined> {\n return this.beforeClosedSubject.asObservable();\n }\n\n /** Observable that emits once after the dialog has fully closed and the overlay is disposed. */\n afterClosed(): Observable<R | undefined> {\n return this.afterClosedSubject.asObservable();\n }\n\n /** Backdrop click stream (emits even when `disableClose` is set). */\n backdropClick(): Observable<MouseEvent> {\n return this.cdkRef.backdropClick;\n }\n\n /** Keydown event stream for the overlay. */\n keydownEvents(): Observable<KeyboardEvent> {\n return this.cdkRef.keydownEvents;\n }\n\n /** Updates the dialog's width/height. Pass empty string to reset a dimension. */\n updateSize(width: string | number = '', height: string | number = ''): this {\n this.cdkRef.updateSize(width, height);\n return this;\n }\n\n /** Adds CSS classes to the overlay panel. */\n addPanelClass(classes: string | string[]): this {\n this.cdkRef.addPanelClass(classes);\n return this;\n }\n\n /** Removes CSS classes from the overlay panel. */\n removePanelClass(classes: string | string[]): this {\n this.cdkRef.removePanelClass(classes);\n return this;\n }\n\n private closeWithOrigin(origin: FocusOrigin, result?: R): void {\n if (this.stateSignal() === 'closing' || this.stateSignal() === 'closed') return;\n\n const predicate = this.config.closePredicate;\n if (\n predicate &&\n !predicate(\n result,\n this.config as unknown as Parameters<typeof predicate>[1],\n this.componentInstance,\n )\n ) {\n return;\n }\n\n this.pendingResult = result;\n this.closeFocusOrigin = origin;\n this.stateSignal.set('closing');\n\n this.beforeClosedSubject.next(result);\n this.beforeClosedSubject.complete();\n\n this.cdkRef.overlayRef.detachBackdrop();\n this.containerInstance._startExitAnimation();\n }\n\n private finishClose(): void {\n if (this.stateSignal() === 'closed') return;\n this.stateSignal.set('closed');\n\n this.afterClosedSubject.next(this.pendingResult);\n this.afterClosedSubject.complete();\n\n if (this.cdkRef.containerInstance) {\n this.cdkRef.close(this.pendingResult, { focusOrigin: this.closeFocusOrigin });\n }\n\n this.componentInstance = null;\n }\n}\n","import {\n type ComponentRef,\n inject,\n Injectable,\n Injector,\n type OnDestroy,\n type Provider,\n type StaticProvider,\n type TemplateRef,\n signal,\n type Signal,\n makeEnvironmentProviders,\n type EnvironmentProviders,\n} from '@angular/core';\nimport { Dialog, DialogConfig as CdkDialogConfig } from '@angular/cdk/dialog';\nimport {\n createBlockScrollStrategy,\n createCloseScrollStrategy,\n createNoopScrollStrategy,\n createRepositionScrollStrategy,\n type ScrollStrategy,\n} from '@angular/cdk/overlay';\nimport type { ComponentType } from '@angular/cdk/portal';\nimport { defer, type Observable, startWith, Subject } from 'rxjs';\nimport {\n TW_DIALOG_DATA,\n TW_DIALOG_DEFAULT_OPTIONS,\n TwDialogConfig,\n type TwDialogScrollStrategy,\n} from './dialog-config';\nimport { DialogContainer } from './dialog-container';\nimport { TwDialogRef } from './dialog-ref';\n\n/**\n * Opens Tailwind-styled modal dialogs. Composes `@angular/cdk/dialog` for focus\n * trapping, portals, overlay plumbing, and adds a Tailwind container, richer\n * ref API, and animation lifecycle.\n *\n * Not `providedIn: 'root'` — register it via {@link provideTwDialog}.\n */\n@Injectable()\nexport class TwDialog implements OnDestroy {\n private readonly cdkDialog = inject(Dialog);\n private readonly injector = inject(Injector);\n private readonly defaultOptions = inject(TW_DIALOG_DEFAULT_OPTIONS, { optional: true }) ?? {};\n private readonly parentDialog = inject(TwDialog, { optional: true, skipSelf: true });\n\n private readonly openDialogsAtThisLevel = signal<readonly TwDialogRef<unknown, unknown>[]>([]);\n private readonly afterOpenedSubject = new Subject<TwDialogRef<unknown, unknown>>();\n private readonly afterAllClosedSubject = new Subject<void>();\n\n /** Reactively-readable list of currently-open dialogs across the full dialog tree. */\n readonly openDialogs: Signal<readonly TwDialogRef<unknown, unknown>[]> = this.parentDialog\n ? this.parentDialog.openDialogs\n : this.openDialogsAtThisLevel.asReadonly();\n\n /** Emits every time a dialog is opened. */\n readonly afterOpened: Observable<TwDialogRef<unknown, unknown>> = this.parentDialog\n ? this.parentDialog.afterOpened\n : this.afterOpenedSubject.asObservable();\n\n /**\n * Emits when every open dialog has closed. Emits immediately on subscribe if\n * there are none open.\n */\n readonly afterAllClosed: Observable<void> = defer(() =>\n this.openDialogs().length\n ? this.getAfterAllClosedSource()\n : this.getAfterAllClosedSource().pipe(startWith(undefined as void)),\n );\n\n /**\n * Opens a dialog using the given component or template.\n * @param content Component class or `TemplateRef`.\n * @param config Options merged over the application defaults.\n * @returns Reference controlling the opened dialog.\n */\n open<R = unknown, D = unknown, C = unknown>(\n content: ComponentType<C> | TemplateRef<C>,\n config?: TwDialogConfig<D, R>,\n ): TwDialogRef<R, C> {\n const merged = this.resolveConfig<D, R>(config);\n let twRef!: TwDialogRef<R, C>;\n\n const cdkRef = this.cdkDialog.open<R, D, C>(content, {\n id: merged.id,\n role: merged.role,\n data: merged.data,\n panelClass: merged.panelClass,\n backdropClass: merged.backdropClass ?? 'tw-dialog-backdrop',\n hasBackdrop: merged.hasBackdrop,\n width: merged.width,\n height: merged.height,\n minWidth: merged.minWidth,\n minHeight: merged.minHeight,\n maxWidth: merged.maxWidth,\n maxHeight: merged.maxHeight,\n direction: merged.direction,\n ariaDescribedBy: merged.ariaDescribedBy,\n ariaLabelledBy: merged.ariaLabelledBy,\n ariaLabel: merged.ariaLabel,\n ariaModal: merged.ariaModal,\n autoFocus: merged.autoFocus,\n restoreFocus: merged.restoreFocus,\n scrollStrategy: merged.scrollStrategy ?? this.resolveScrollStrategy(merged.scrollBehavior),\n closeOnNavigation: merged.closeOnNavigation,\n viewContainerRef: merged.viewContainerRef,\n injector: merged.injector,\n // We handle close/Escape/backdrop ourselves so we can run the exit animation.\n disableClose: true,\n closeOnOverlayDetachments: false,\n container: {\n type: DialogContainer,\n providers: () => [\n { provide: TwDialogConfig, useValue: merged },\n { provide: CdkDialogConfig, useValue: merged },\n ],\n },\n providers: (_cdkRef, _cdkConfig, container) => {\n twRef = new TwDialogRef<R, C>(\n _cdkRef,\n merged as unknown as TwDialogConfig<unknown, R>,\n container as DialogContainer,\n );\n const providers: StaticProvider[] = [\n { provide: TwDialogRef, useValue: twRef },\n { provide: TW_DIALOG_DATA, useValue: merged.data ?? null },\n ];\n if (Array.isArray(merged.providers)) providers.push(...merged.providers);\n return providers;\n },\n });\n\n // After CDK attaches the component, copy references onto our ref.\n (twRef as { componentRef: ComponentRef<C> | null }).componentRef = cdkRef.componentRef;\n twRef.componentInstance = cdkRef.componentInstance as C | null;\n\n const scope = this.parentDialog ?? this;\n scope.registerOpen(twRef as unknown as TwDialogRef<unknown, unknown>);\n\n twRef.afterClosed().subscribe(() => {\n scope.unregister(twRef as unknown as TwDialogRef<unknown, unknown>);\n });\n\n return twRef;\n }\n\n /** Closes every open dialog managed by this service (and child services). */\n closeAll(): void {\n const dialogs = [...this.openDialogs()];\n for (let i = dialogs.length - 1; i >= 0; i--) dialogs[i].close();\n }\n\n /** Looks up an open dialog by its id. */\n getDialogById<R = unknown, C = unknown>(id: string): TwDialogRef<R, C> | undefined {\n return this.openDialogs().find((dialog) => dialog.id === id) as TwDialogRef<R, C> | undefined;\n }\n\n ngOnDestroy(): void {\n const dialogs = [...this.openDialogsAtThisLevel()];\n for (let i = dialogs.length - 1; i >= 0; i--) dialogs[i].close();\n this.afterOpenedSubject.complete();\n this.afterAllClosedSubject.complete();\n }\n\n private registerOpen(ref: TwDialogRef<unknown, unknown>): void {\n if (this.parentDialog) {\n this.parentDialog.registerOpen(ref);\n } else {\n this.openDialogsAtThisLevel.update((list) => [...list, ref]);\n this.afterOpenedSubject.next(ref);\n }\n }\n\n private unregister(ref: TwDialogRef<unknown, unknown>): void {\n if (this.parentDialog) {\n this.parentDialog.unregister(ref);\n } else {\n this.openDialogsAtThisLevel.update((list) => list.filter((d) => d !== ref));\n if (this.openDialogsAtThisLevel().length === 0) {\n this.afterAllClosedSubject.next();\n }\n }\n }\n\n private getAfterAllClosedSource(): Subject<void> {\n return this.parentDialog\n ? this.parentDialog.getAfterAllClosedSource()\n : this.afterAllClosedSubject;\n }\n\n private resolveConfig<D, R>(config: TwDialogConfig<D, R> | undefined): TwDialogConfig<D, R> {\n const merged = new TwDialogConfig<D, R>();\n Object.assign(merged, this.defaultOptions, config);\n return merged;\n }\n\n private resolveScrollStrategy(\n strategy: TwDialogScrollStrategy | undefined,\n ): ScrollStrategy {\n switch (strategy) {\n case 'close':\n return createCloseScrollStrategy(this.injector);\n case 'reposition':\n return createRepositionScrollStrategy(this.injector);\n case 'noop':\n return createNoopScrollStrategy();\n case 'block':\n default:\n return createBlockScrollStrategy(this.injector);\n }\n }\n}\n\n/**\n * Registers the {@link TwDialog} service for dependency injection.\n *\n * @param defaultOptions Optional defaults merged into every `open()` call.\n * @example\n * ```ts\n * provideTwDialog({ size: 'lg', hasBackdrop: true })\n * ```\n */\nexport function provideTwDialog(\n defaultOptions?: Partial<TwDialogConfig>,\n): EnvironmentProviders {\n const providers: Provider[] = [TwDialog];\n if (defaultOptions) {\n providers.push({ provide: TW_DIALOG_DEFAULT_OPTIONS, useValue: defaultOptions });\n }\n return makeEnvironmentProviders(providers);\n}\n","import {\n computed,\n Directive,\n inject,\n input,\n type OnDestroy,\n type OnInit,\n} from '@angular/core';\nimport { _IdGenerator } from '@angular/cdk/a11y';\nimport { CdkScrollable } from '@angular/cdk/scrolling';\nimport type { TwColor } from '@cdevhub/ngx-tw/core';\nimport { TwDialogRef } from './dialog-ref';\nimport { DialogContainer } from './dialog-container';\n\n/**\n * Header wrapper for a dialog. Provides consistent padding and spacing for\n * title + subtitle + leading icon, and separates the header from scrollable\n * content below.\n */\n@Directive({\n selector: '[twDialogHeader], tw-dialog-header',\n host: {\n class: 'flex items-start gap-3 px-6 pt-6 pb-4',\n },\n})\nexport class DialogHeaderDirective {}\n\n// Slot tokens own light/dark contrast — no `dark:` overrides, no shade picks.\n// See role slot conventions in `projects/ngx-tw/theme/_semantic.css`.\nconst ICON_COLOR_CLASSES: Record<TwColor, string> = {\n primary: 'bg-primary-soft text-primary-icon',\n secondary: 'bg-secondary-soft text-secondary-icon',\n accent: 'bg-accent-soft text-accent-icon',\n neutral: 'bg-neutral-soft text-neutral-icon',\n info: 'bg-info-soft text-info-icon',\n success: 'bg-success-soft text-success-icon',\n warning: 'bg-warning-soft text-warning-icon',\n error: 'bg-error-soft text-error-icon',\n};\n\n/**\n * Decorative leading icon for a dialog header. Use with a semantic `color` to\n * match destructive / informational / success dialogs.\n */\n@Directive({\n selector: '[twDialogIcon]',\n host: {\n '[class]': 'classes()',\n },\n})\nexport class DialogIconDirective {\n /** Semantic color for the icon container. Defaults to a neutral surface. */\n readonly color = input<TwColor | undefined>(undefined);\n\n protected readonly classes = computed(() => {\n const base = 'flex size-10 shrink-0 items-center justify-center rounded-full';\n const color = this.color();\n return color ? `${base} ${ICON_COLOR_CLASSES[color]}` : `${base} bg-surface-muted text-fg`;\n });\n}\n\n/**\n * Dialog title. Registers its ID with the container's `aria-labelledby` queue\n * so screen readers announce it automatically.\n */\n@Directive({\n selector: '[twDialogTitle], tw-dialog-title',\n host: {\n class: 'text-sm font-semibold text-fg',\n '[id]': 'id()',\n },\n})\nexport class DialogTitleDirective implements OnInit, OnDestroy {\n private readonly generatedId = inject(_IdGenerator).getId('tw-dialog-title-');\n private readonly dialogRef = inject<TwDialogRef<unknown, unknown>>(TwDialogRef, {\n optional: true,\n });\n // Ancestor-DI fallback for the rare case where `TwDialogRef` is not in the\n // directive's injector chain (e.g. heavily nested template portals). The\n // container ALWAYS resolves via element-injector traversal because the\n // directive lives inside `<tw-dialog-container>`'s DOM tree.\n private readonly container = inject(DialogContainer, { optional: true, skipSelf: true });\n\n /** Custom id for the title element. Defaults to a generated unique id. */\n readonly id = input<string>(this.generatedId);\n\n ngOnInit(): void {\n const containerInstance = this.dialogRef?.containerInstance ?? this.container;\n if (containerInstance) containerInstance._addAriaLabelledBy(this.id());\n }\n\n ngOnDestroy(): void {\n const containerInstance = this.dialogRef?.containerInstance ?? this.container;\n if (containerInstance) containerInstance._removeAriaLabelledBy(this.id());\n }\n}\n\n/** Secondary line beneath the dialog title — intended for a short description. */\n@Directive({\n selector: '[twDialogSubtitle], tw-dialog-subtitle',\n host: {\n class: 'text-sm text-fg-muted',\n },\n})\nexport class DialogSubtitleDirective {}\n\n/**\n * Dialog description. Registers its ID with the container's `aria-describedby`\n * queue so screen readers announce the descriptive paragraph after the title.\n * Mirrors {@link DialogTitleDirective} but for `aria-describedby`.\n */\n@Directive({\n selector: '[twDialogDescription], tw-dialog-description',\n host: {\n '[id]': 'id()',\n },\n})\nexport class DialogDescriptionDirective implements OnInit, OnDestroy {\n private readonly generatedId = inject(_IdGenerator).getId('tw-dialog-description-');\n private readonly dialogRef = inject<TwDialogRef<unknown, unknown>>(TwDialogRef, {\n optional: true,\n });\n // Ancestor-DI fallback — see DialogTitleDirective.\n private readonly container = inject(DialogContainer, { optional: true, skipSelf: true });\n\n /** Custom id for the description element. Defaults to a generated unique id. */\n readonly id = input<string>(this.generatedId);\n\n ngOnInit(): void {\n const containerInstance = this.dialogRef?.containerInstance ?? this.container;\n if (containerInstance) containerInstance._addAriaDescribedBy(this.id());\n }\n\n ngOnDestroy(): void {\n const containerInstance = this.dialogRef?.containerInstance ?? this.container;\n if (containerInstance) containerInstance._removeAriaDescribedBy(this.id());\n }\n}\n\n/**\n * Scrollable content region of the dialog. Apply between the header and the\n * actions bar. Inherits CDK's `CdkScrollable` to play nicely with scroll\n * strategies and nested scrollables.\n */\n@Directive({\n selector: '[twDialogContent], tw-dialog-content',\n hostDirectives: [CdkScrollable],\n host: {\n class: 'flex-1 overflow-y-auto px-6 py-4 text-sm text-fg',\n },\n})\nexport class DialogContentDirective {}\n\n/** Horizontal alignment for dialog action buttons. */\nexport type DialogActionsAlign = 'start' | 'center' | 'end';\n\n/**\n * Bottom action bar of a dialog. Use inside the dialog content or template to\n * host Cancel/Confirm buttons. Stays pinned below scrollable content.\n */\n@Directive({\n selector: '[twDialogActions], tw-dialog-actions',\n host: {\n '[class]': 'classes()',\n },\n})\nexport class DialogActionsDirective {\n /** Horizontal alignment of the action buttons. Defaults to `'end'`. */\n readonly align = input<DialogActionsAlign>('end');\n\n protected readonly classes = computed(() => {\n const align = this.align();\n const justify =\n align === 'start' ? 'justify-start' : align === 'center' ? 'justify-center' : 'justify-end';\n return `flex flex-wrap items-center gap-2 px-6 py-4 border-t border-border-muted ${justify}`;\n });\n}\n\n/**\n * Closes the enclosing dialog when the host button is clicked. Provide a\n * `[twDialogClose]` value to pass a result to `afterClosed()` subscribers.\n */\n@Directive({\n selector: '[twDialogClose]',\n host: {\n '(click)': 'onClick()',\n '[attr.type]': 'type()',\n },\n})\nexport class DialogCloseDirective {\n /** Value passed to `afterClosed()` when the button is clicked. */\n readonly twDialogClose = input<unknown>(undefined);\n\n /** Native button `type`. Defaults to `'button'` to avoid accidental form submission. */\n readonly type = input<'button' | 'submit' | 'reset'>('button');\n\n private readonly dialogRef = inject<TwDialogRef<unknown, unknown>>(TwDialogRef, {\n optional: true,\n });\n\n protected onClick(): void {\n this.dialogRef?.close(this.twDialogClose());\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["CdkDialogConfig"],"mappings":"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"}
1
+ {"version":3,"file":"cdevhub-ngx-tw-dialog.mjs","sources":["../../../projects/ngx-tw/dialog/dialog-config.ts","../../../projects/ngx-tw/dialog/dialog-ref.ts","../../../projects/ngx-tw/dialog/dialog.ts","../../../projects/ngx-tw/dialog/dialog-content.ts","../../../projects/ngx-tw/dialog/cdevhub-ngx-tw-dialog.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport {\n type AutoFocusTarget,\n DialogConfig as CdkDialogConfig,\n type DialogRole,\n type RestoreFocusValue,\n} from '@angular/cdk/dialog';\n\n/** Preset sizes mapped to width constraints for the dialog panel. */\nexport type TwDialogSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'fullscreen';\n\n/** ARIA role of the dialog element. Use `'alertdialog'` for destructive confirmation prompts. */\nexport type TwDialogRole = DialogRole;\n\n/** Where to move focus when the dialog opens. */\nexport type TwDialogAutoFocus = AutoFocusTarget | string | boolean;\n\n/** How to restore focus on close. `true` restores to the previously focused element; a selector or element targets a specific node. */\nexport type TwDialogRestoreFocus = RestoreFocusValue;\n\n/** Scroll behavior for content underneath the dialog. */\nexport type TwDialogScrollStrategy = 'block' | 'close' | 'reposition' | 'noop';\n\n/**\n * Configuration for opening a dialog with {@link TwDialog.open}.\n *\n * Mirrors the shape of `@angular/cdk/dialog`'s `DialogConfig` with additional\n * tailwind-focused options (`size`, `enterAnimationDuration`, etc.).\n */\nexport class TwDialogConfig<D = unknown, R = unknown> extends CdkDialogConfig<D, R> {\n /** Preset size for the dialog panel. Ignored when `width`/`maxWidth` are provided. Defaults to `'md'`. */\n size?: TwDialogSize = 'md';\n\n /** Duration of the open animation in ms. Defaults to `150`. Use `0` to disable. */\n enterAnimationDuration?: number = 150;\n\n /**\n * Duration of the close animation in ms. Defaults to `120`. Use `0` to disable.\n * Asymmetric with `enterAnimationDuration` by design: the close transition is\n * slightly faster so the dialog feels dismissive rather than reluctant.\n */\n exitAnimationDuration?: number = 120;\n\n /** Scroll strategy preset applied when `scrollStrategy` isn't set. Defaults to `'block'`. */\n scrollBehavior?: TwDialogScrollStrategy = 'block';\n\n /** Maximum width. Number values are treated as pixels. Defaults to `'calc(100vw - 32px)'`. */\n override maxWidth?: number | string = 'calc(100vw - 32px)';\n\n /**\n * Whether the dialog is modal — sets `aria-modal` on the container.\n * Defaults to `true`: a `role=\"dialog\"` opened over the page is modal by\n * default and the rest of the document is inert while it is open. Set to\n * `false` only for non-modal surfaces (rare; consider `popover` instead).\n */\n override ariaModal?: boolean = true;\n\n /** Whether Escape and backdrop clicks are blocked. Defaults to `false`. */\n override disableClose?: boolean = false;\n\n /** Where to move focus when the dialog opens. Defaults to `'first-tabbable'`. */\n override autoFocus?: TwDialogAutoFocus = 'first-tabbable';\n\n /** Whether to restore focus to the previously focused element after close. Defaults to `true`. */\n override restoreFocus?: TwDialogRestoreFocus = true;\n\n /** Whether the dialog renders a backdrop. Defaults to `true`. */\n override hasBackdrop?: boolean = true;\n\n /** Whether navigation (e.g. router) closes the dialog. Defaults to `true`. */\n override closeOnNavigation?: boolean = true;\n}\n\n/** Injection token carrying the `data` value passed via {@link TwDialogConfig.data}. */\nexport const TW_DIALOG_DATA = new InjectionToken<unknown>('TW_DIALOG_DATA');\n\n/** Injection token for application-wide default dialog options. Set via `provideTwDialog()`. */\nexport const TW_DIALOG_DEFAULT_OPTIONS = new InjectionToken<Partial<TwDialogConfig>>(\n 'TW_DIALOG_DEFAULT_OPTIONS',\n);\n","import { type ComponentRef, signal, type Signal } from '@angular/core';\nimport { type DialogRef as CdkDialogRef } from '@angular/cdk/dialog';\nimport { ESCAPE, hasModifierKey } from '@angular/cdk/keycodes';\nimport { filter, merge, type Observable, ReplaySubject, Subject, take } from 'rxjs';\nimport type { FocusOrigin } from '@angular/cdk/a11y';\nimport type { TwDialogConfig } from './dialog-config';\nimport type { DialogContainer, DialogState } from './dialog-container';\n\n/**\n * Reference to a dialog opened via {@link TwDialog.open}. Drives the dialog\n * lifecycle (close, state, observables) and forwards useful overlay streams.\n *\n * The ref is returned **synchronously** from `open()`, but the dialog's render\n * layer (`@angular/cdk/dialog` + the Tailwind container) is loaded through a\n * dynamic `import()`. The ref therefore starts *detached*: `id`, `state`,\n * `close()`, the lifecycle observables, and panel/size mutations all work\n * immediately (mutations are buffered and replayed on attach), but the rendered\n * component instance does not exist yet — read it via {@link whenComponentReady}\n * instead of a synchronous `componentInstance` field.\n */\nexport class TwDialogRef<R = unknown, C = unknown> {\n /** Unique ID of the dialog. Generated eagerly by the service, so it is valid the instant `open()` returns. */\n readonly id: string;\n\n /** Current lifecycle state. Reactively readable. */\n readonly state: Signal<DialogState>;\n\n /** When `true`, close-via-escape and close-via-backdrop are disabled. */\n disableClose: boolean | undefined;\n\n private readonly stateSignal = signal<DialogState>('opening');\n private readonly afterOpenedSubject = new ReplaySubject<void>(1);\n private readonly beforeClosedSubject = new ReplaySubject<R | undefined>(1);\n private readonly afterClosedSubject = new ReplaySubject<R | undefined>(1);\n // Facade-owned pass-throughs for the raw overlay streams, so a consumer that\n // subscribes before the render chunk attaches still receives events once it\n // does — the pre-deferral behaviour when `open()` wrapped a live `cdkRef`.\n private readonly backdropClickSubject = new Subject<MouseEvent>();\n private readonly keydownEventsSubject = new Subject<KeyboardEvent>();\n\n private cdkRef: CdkDialogRef<R, C> | null = null;\n private container: DialogContainer | null = null;\n\n private componentInstanceValue: C | null = null;\n private componentRefValue: ComponentRef<C> | null = null;\n private resolveComponentReady!: (value: C | null) => void;\n private readonly componentReadyPromise = new Promise<C | null>((resolve) => {\n this.resolveComponentReady = resolve;\n });\n\n // Buffered mutations issued before the render chunk attached the CDK backend.\n private readonly pendingPanelAdds: string[] = [];\n private readonly pendingPanelRemoves: string[] = [];\n private pendingSize: [string | number, string | number] | null = null;\n\n private pendingResult: R | undefined;\n private closeFocusOrigin: FocusOrigin | undefined;\n\n constructor(id: string, readonly config: TwDialogConfig<unknown, R>) {\n this.id = id;\n this.disableClose = config.disableClose;\n this.state = this.stateSignal.asReadonly();\n }\n\n /**\n * The Tailwind container instance, or `null` until the dialog has attached.\n * `null` is the normal value for the first tick after `open()` returns,\n * because the render layer is loaded through a dynamic `import()`.\n *\n * Only `state`, `animationStateChanged`, `enterAnimationDuration` and\n * `exitAnimationDuration` are supported reads; the `_`-prefixed members are\n * library-internal wiring and may change without a major bump. Prefer\n * {@link state} and {@link afterOpened} on the ref itself.\n */\n get containerInstance(): DialogContainer | null {\n return this.container;\n }\n\n /**\n * @internal Wire this facade to its CDK backend. Called from the dialog\n * renderer **inside** `cdkDialog.open()`'s `providers` callback — the same\n * point the constructor ran before deferral — so subscriptions to\n * `animationStateChanged` are in place before the container emits `'open'`.\n */\n _attach(cdkRef: CdkDialogRef<R, C>, container: DialogContainer): void {\n this.cdkRef = cdkRef;\n this.container = container;\n\n // Forward the raw overlay streams into the facade pass-throughs.\n cdkRef.backdropClick.subscribe(this.backdropClickSubject);\n cdkRef.keydownEvents.subscribe(this.keydownEventsSubject);\n\n cdkRef.addPanelClass('tw-dialog-panel');\n for (const cls of this.pendingPanelAdds) cdkRef.addPanelClass(cls);\n for (const cls of this.pendingPanelRemoves) cdkRef.removePanelClass(cls);\n if (this.pendingSize) cdkRef.updateSize(this.pendingSize[0], this.pendingSize[1]);\n this.pendingPanelAdds.length = 0;\n this.pendingPanelRemoves.length = 0;\n this.pendingSize = null;\n\n const animationChanges = container.animationStateChanged;\n\n animationChanges\n .pipe(\n filter((event) => event.state === 'open'),\n take(1),\n )\n .subscribe(() => {\n this.stateSignal.set('open');\n this.afterOpenedSubject.next();\n this.afterOpenedSubject.complete();\n });\n\n // The container owns the exit-animation fallback timer (see\n // ANIMATION_FALLBACK_PADDING in dialog-container.ts), so we trust its\n // `closed` emission and run finishClose exactly once from here.\n animationChanges\n .pipe(\n filter((event) => event.state === 'closed'),\n take(1),\n )\n .subscribe(() => this.finishClose());\n\n cdkRef.overlayRef.detachments().subscribe(() => {\n if (this.stateSignal() !== 'closed') {\n this.beforeClosedSubject.next(this.pendingResult);\n this.beforeClosedSubject.complete();\n this.finishClose();\n }\n });\n\n merge(\n cdkRef.backdropClick,\n cdkRef.keydownEvents.pipe(\n filter(\n (event) => event.keyCode === ESCAPE && !this.disableClose && !hasModifierKey(event),\n ),\n ),\n ).subscribe((event) => {\n if (this.disableClose) return;\n event.preventDefault();\n this.closeWithOrigin(event.type === 'keydown' ? 'keyboard' : 'mouse');\n });\n }\n\n /** @internal Record the rendered component after `cdkDialog.open()` returns. */\n _setComponent(instance: C | null, ref: ComponentRef<C> | null): void {\n this.componentInstanceValue = instance;\n this.componentRefValue = ref;\n this.resolveComponentReady(instance);\n }\n\n /**\n * Resolves with the rendered content-component instance once the dialog's\n * render chunk has loaded and attached. Resolves `null` for template dialogs,\n * and for a dialog closed before it ever opened.\n *\n * Replaces the former synchronous `componentInstance` field, which cannot be\n * populated before the deferred render chunk lands.\n *\n * @example\n * ```ts\n * const ref = dialog.open(EditorDialog);\n * const editor = await ref.whenComponentReady();\n * editor?.focusFirstField();\n * ```\n */\n whenComponentReady(): Promise<C | null> {\n return this.componentReadyPromise;\n }\n\n /** The rendered component instance, or `null` if not yet attached / a template dialog. Prefer {@link whenComponentReady}. */\n get componentInstance(): C | null {\n return this.componentInstanceValue;\n }\n\n /** The rendered `ComponentRef`, or `null` if not yet attached / a template dialog. */\n get componentRef(): ComponentRef<C> | null {\n return this.componentRefValue;\n }\n\n /**\n * Closes the dialog. The exit animation runs before the overlay is disposed.\n * @param result Value forwarded to `afterClosed()` subscribers.\n */\n close(result?: R): void {\n this.closeWithOrigin('program', result);\n }\n\n /** Observable that emits once after the enter animation finishes. */\n afterOpened(): Observable<void> {\n return this.afterOpenedSubject.asObservable();\n }\n\n /** Observable that emits once when the close animation starts. */\n beforeClosed(): Observable<R | undefined> {\n return this.beforeClosedSubject.asObservable();\n }\n\n /** Observable that emits once after the dialog has fully closed and the overlay is disposed. */\n afterClosed(): Observable<R | undefined> {\n return this.afterClosedSubject.asObservable();\n }\n\n /** Backdrop click stream (emits even when `disableClose` is set). Buffered — a subscription made before the dialog attaches receives events once it does. */\n backdropClick(): Observable<MouseEvent> {\n return this.backdropClickSubject.asObservable();\n }\n\n /** Keydown event stream for the overlay. Buffered — a subscription made before the dialog attaches receives events once it does. */\n keydownEvents(): Observable<KeyboardEvent> {\n return this.keydownEventsSubject.asObservable();\n }\n\n /** Updates the dialog's width/height. Pass empty string to reset a dimension. Buffered until attach. */\n updateSize(width: string | number = '', height: string | number = ''): this {\n if (this.cdkRef) {\n this.cdkRef.updateSize(width, height);\n } else {\n this.pendingSize = [width, height];\n }\n return this;\n }\n\n /** Adds CSS classes to the overlay panel. Buffered until attach. */\n addPanelClass(classes: string | string[]): this {\n if (this.cdkRef) {\n this.cdkRef.addPanelClass(classes);\n } else {\n this.pendingPanelAdds.push(...(Array.isArray(classes) ? classes : [classes]));\n }\n return this;\n }\n\n /** Removes CSS classes from the overlay panel. Buffered until attach. */\n removePanelClass(classes: string | string[]): this {\n if (this.cdkRef) {\n this.cdkRef.removePanelClass(classes);\n } else {\n this.pendingPanelRemoves.push(...(Array.isArray(classes) ? classes : [classes]));\n }\n return this;\n }\n\n private closeWithOrigin(origin: FocusOrigin, result?: R): void {\n if (this.stateSignal() === 'closing' || this.stateSignal() === 'closed') return;\n\n const predicate = this.config.closePredicate;\n if (\n predicate &&\n !predicate(\n result,\n this.config as unknown as Parameters<typeof predicate>[1],\n this.componentInstanceValue,\n )\n ) {\n return;\n }\n\n this.pendingResult = result;\n this.closeFocusOrigin = origin;\n this.stateSignal.set('closing');\n\n this.beforeClosedSubject.next(result);\n this.beforeClosedSubject.complete();\n\n if (!this.cdkRef) {\n // Closed before the render chunk attached: the overlay was never created,\n // so there is nothing to animate or dispose. Synthesize the closed state\n // and let the service skip opening entirely (it checks state()).\n this.finishClose();\n return;\n }\n\n this.cdkRef.overlayRef.detachBackdrop();\n this.container!._startExitAnimation();\n }\n\n private finishClose(): void {\n if (this.stateSignal() === 'closed') return;\n this.stateSignal.set('closed');\n\n this.afterClosedSubject.next(this.pendingResult);\n this.afterClosedSubject.complete();\n\n // Idempotent — a no-op if _setComponent already resolved with an instance.\n this.resolveComponentReady(null);\n this.backdropClickSubject.complete();\n this.keydownEventsSubject.complete();\n\n if (this.cdkRef?.containerInstance) {\n this.cdkRef.close(this.pendingResult, { focusOrigin: this.closeFocusOrigin });\n }\n\n this.componentInstanceValue = null;\n }\n}\n","import {\n inject,\n Injectable,\n Injector,\n type OnDestroy,\n type Provider,\n type TemplateRef,\n signal,\n type Signal,\n makeEnvironmentProviders,\n type EnvironmentProviders,\n} from '@angular/core';\nimport type { ComponentType } from '@angular/cdk/portal';\nimport { defer, type Observable, startWith, Subject } from 'rxjs';\nimport {\n TW_DIALOG_DEFAULT_OPTIONS,\n TwDialogConfig,\n} from './dialog-config';\nimport { TwDialogRef } from './dialog-ref';\n// Type-only: importing the renderer as a value would drag `@angular/cdk/dialog`\n// and the overlay scroll strategies back into the eager chunk. See\n// `dialog-renderer.ts`.\nimport type { openRenderedDialog } from './dialog-renderer';\n\nlet nextDialogId = 0;\n\nfunction generateDialogId(): string {\n return `tw-dialog-${++nextDialogId}`;\n}\n\n/**\n * Opens Tailwind-styled modal dialogs. Composes `@angular/cdk/dialog` for focus\n * trapping, portals, overlay plumbing, and adds a Tailwind container, richer\n * ref API, and animation lifecycle.\n *\n * The rendering layer (`@angular/cdk/dialog` + the Tailwind container) is loaded\n * through a dynamic `import()` on the first `open()` call, so merely registering\n * this service costs nothing in the initial bundle. `open()` still returns its\n * {@link TwDialogRef} synchronously — the dialog is rendered once the chunk\n * lands. Read the rendered component via {@link TwDialogRef.whenComponentReady}.\n *\n * Not `providedIn: 'root'` — register it via {@link provideTwDialog}.\n */\n@Injectable()\nexport class TwDialog implements OnDestroy {\n private readonly injector = inject(Injector);\n private readonly defaultOptions = inject(TW_DIALOG_DEFAULT_OPTIONS, { optional: true }) ?? {};\n private readonly parentDialog = inject(TwDialog, { optional: true, skipSelf: true });\n\n /** Cached renderer chunk import — kicked off on the first `open()`. */\n private rendererPromise: Promise<typeof openRenderedDialog | null> | null = null;\n private destroyed = false;\n\n private readonly openDialogsAtThisLevel = signal<readonly TwDialogRef<unknown, unknown>[]>([]);\n private readonly afterOpenedSubject = new Subject<TwDialogRef<unknown, unknown>>();\n private readonly afterAllClosedSubject = new Subject<void>();\n\n /** Reactively-readable list of currently-open dialogs across the full dialog tree. */\n readonly openDialogs: Signal<readonly TwDialogRef<unknown, unknown>[]> = this.parentDialog\n ? this.parentDialog.openDialogs\n : this.openDialogsAtThisLevel.asReadonly();\n\n /** Emits every time a dialog is opened. */\n readonly afterOpened: Observable<TwDialogRef<unknown, unknown>> = this.parentDialog\n ? this.parentDialog.afterOpened\n : this.afterOpenedSubject.asObservable();\n\n /**\n * Emits when every open dialog has closed. Emits immediately on subscribe if\n * there are none open.\n */\n readonly afterAllClosed: Observable<void> = defer(() =>\n this.openDialogs().length\n ? this.getAfterAllClosedSource()\n : this.getAfterAllClosedSource().pipe(startWith(undefined as void)),\n );\n\n /**\n * Opens a dialog using the given component or template.\n * @param content Component class or `TemplateRef`.\n * @param config Options merged over the application defaults.\n * @returns Reference controlling the opened dialog, returned synchronously.\n */\n open<R = unknown, D = unknown, C = unknown>(\n content: ComponentType<C> | TemplateRef<C>,\n config?: TwDialogConfig<D, R>,\n ): TwDialogRef<R, C> {\n const merged = this.resolveConfig<D, R>(config);\n const id = merged.id ?? generateDialogId();\n merged.id = id;\n\n // Enforce id uniqueness eagerly. CDK throws this synchronously from\n // `open()`; since our CDK open is now deferred, replicate the check here so\n // the error still surfaces at the call site rather than in a later tick.\n if (this.getDialogById(id)) {\n throw new Error(`Dialog with id \"${id}\" exists already. The dialog id must be unique.`);\n }\n\n const twRef = new TwDialogRef<R, C>(id, merged as unknown as TwDialogConfig<unknown, R>);\n\n const scope = this.parentDialog ?? this;\n scope.registerOpen(twRef as unknown as TwDialogRef<unknown, unknown>);\n twRef.afterClosed().subscribe(() => {\n scope.unregister(twRef as unknown as TwDialogRef<unknown, unknown>);\n });\n\n void this.renderWhenReady(content, merged, twRef);\n\n return twRef;\n }\n\n /** Closes every open dialog managed by this service (and child services). */\n closeAll(): void {\n const dialogs = [...this.openDialogs()];\n for (let i = dialogs.length - 1; i >= 0; i--) dialogs[i].close();\n }\n\n /** Looks up an open dialog by its id. */\n getDialogById<R = unknown, C = unknown>(id: string): TwDialogRef<R, C> | undefined {\n return this.openDialogs().find((dialog) => dialog.id === id) as TwDialogRef<R, C> | undefined;\n }\n\n ngOnDestroy(): void {\n this.destroyed = true;\n const dialogs = [...this.openDialogsAtThisLevel()];\n for (let i = dialogs.length - 1; i >= 0; i--) dialogs[i].close();\n this.afterOpenedSubject.complete();\n this.afterAllClosedSubject.complete();\n }\n\n /**\n * @internal Resolves once the renderer chunk has loaded. Exposed for tests,\n * which must await the dynamic import before asserting on rendered DOM.\n */\n async _whenRendered(): Promise<void> {\n await this.loadRenderer();\n await Promise.resolve();\n }\n\n /**\n * Render a dialog once the renderer chunk has loaded. The ref was already\n * returned to the caller, so it may have been closed (or the service\n * destroyed) while the import was in flight — both skip the actual open.\n */\n private async renderWhenReady<R, D, C>(\n content: ComponentType<C> | TemplateRef<C>,\n merged: TwDialogConfig<D, R>,\n twRef: TwDialogRef<R, C>,\n ): Promise<void> {\n const openRendered = await this.loadRenderer();\n if (!openRendered || this.destroyed) return;\n // Closed before the chunk landed — the facade already synthesized its\n // closed state; never create the overlay.\n if (twRef.state() === 'closed') return;\n openRendered(this.injector, content, merged, twRef);\n }\n\n private loadRenderer(): Promise<typeof openRenderedDialog | null> {\n if (!this.rendererPromise) {\n this.rendererPromise = import('./dialog-renderer').then(({ openRenderedDialog }) =>\n this.destroyed ? null : openRenderedDialog,\n );\n }\n return this.rendererPromise;\n }\n\n private registerOpen(ref: TwDialogRef<unknown, unknown>): void {\n if (this.parentDialog) {\n this.parentDialog.registerOpen(ref);\n } else {\n this.openDialogsAtThisLevel.update((list) => [...list, ref]);\n this.afterOpenedSubject.next(ref);\n }\n }\n\n private unregister(ref: TwDialogRef<unknown, unknown>): void {\n if (this.parentDialog) {\n this.parentDialog.unregister(ref);\n } else {\n this.openDialogsAtThisLevel.update((list) => list.filter((d) => d !== ref));\n if (this.openDialogsAtThisLevel().length === 0) {\n this.afterAllClosedSubject.next();\n }\n }\n }\n\n private getAfterAllClosedSource(): Subject<void> {\n return this.parentDialog\n ? this.parentDialog.getAfterAllClosedSource()\n : this.afterAllClosedSubject;\n }\n\n private resolveConfig<D, R>(config: TwDialogConfig<D, R> | undefined): TwDialogConfig<D, R> {\n const merged = new TwDialogConfig<D, R>();\n Object.assign(merged, this.defaultOptions, config);\n return merged;\n }\n}\n\n/**\n * Registers the {@link TwDialog} service for dependency injection.\n *\n * @param defaultOptions Optional defaults merged into every `open()` call.\n * @example\n * ```ts\n * provideTwDialog({ size: 'lg', hasBackdrop: true })\n * ```\n */\nexport function provideTwDialog(\n defaultOptions?: Partial<TwDialogConfig>,\n): EnvironmentProviders {\n const providers: Provider[] = [TwDialog];\n if (defaultOptions) {\n providers.push({ provide: TW_DIALOG_DEFAULT_OPTIONS, useValue: defaultOptions });\n }\n return makeEnvironmentProviders(providers);\n}\n","import {\n computed,\n Directive,\n inject,\n input,\n type OnDestroy,\n type OnInit,\n} from '@angular/core';\nimport { _IdGenerator } from '@angular/cdk/a11y';\nimport { CdkScrollable } from '@angular/cdk/scrolling';\nimport type { TwColor } from '@cdevhub/ngx-tw/core';\nimport { TwDialogRef } from './dialog-ref';\n\n/**\n * Header wrapper for a dialog. Provides consistent padding and spacing for\n * title + subtitle + leading icon, and separates the header from scrollable\n * content below.\n */\n@Directive({\n selector: '[twDialogHeader], tw-dialog-header',\n host: {\n class: 'flex items-start gap-3 px-6 pt-6 pb-4',\n },\n})\nexport class DialogHeaderDirective {}\n\n// Slot tokens own light/dark contrast — no `dark:` overrides, no shade picks.\n// See role slot conventions in `projects/ngx-tw/theme/_semantic.css`.\nconst ICON_COLOR_CLASSES: Record<TwColor, string> = {\n primary: 'bg-primary-soft text-primary-icon',\n secondary: 'bg-secondary-soft text-secondary-icon',\n accent: 'bg-accent-soft text-accent-icon',\n neutral: 'bg-neutral-soft text-neutral-icon',\n info: 'bg-info-soft text-info-icon',\n success: 'bg-success-soft text-success-icon',\n warning: 'bg-warning-soft text-warning-icon',\n error: 'bg-error-soft text-error-icon',\n};\n\n/**\n * Decorative leading icon for a dialog header. Use with a semantic `color` to\n * match destructive / informational / success dialogs.\n */\n@Directive({\n selector: '[twDialogIcon]',\n host: {\n '[class]': 'classes()',\n },\n})\nexport class DialogIconDirective {\n /** Semantic color for the icon container. Defaults to a neutral surface. */\n readonly color = input<TwColor | undefined>(undefined);\n\n protected readonly classes = computed(() => {\n const base = 'flex size-10 shrink-0 items-center justify-center rounded-full';\n const color = this.color();\n return color ? `${base} ${ICON_COLOR_CLASSES[color]}` : `${base} bg-surface-muted text-fg`;\n });\n}\n\n/**\n * Dialog title. Registers its ID with the container's `aria-labelledby` queue\n * so screen readers announce it automatically.\n */\n@Directive({\n selector: '[twDialogTitle], tw-dialog-title',\n host: {\n class: 'text-sm font-semibold text-fg',\n '[id]': 'id()',\n },\n})\nexport class DialogTitleDirective implements OnInit, OnDestroy {\n private readonly generatedId = inject(_IdGenerator).getId('tw-dialog-title-');\n private readonly dialogRef = inject<TwDialogRef<unknown, unknown>>(TwDialogRef, {\n optional: true,\n });\n\n /** Custom id for the title element. Defaults to a generated unique id. */\n readonly id = input<string>(this.generatedId);\n\n ngOnInit(): void {\n const containerInstance = this.dialogRef?.containerInstance;\n if (containerInstance) containerInstance._addAriaLabelledBy(this.id());\n }\n\n ngOnDestroy(): void {\n const containerInstance = this.dialogRef?.containerInstance;\n if (containerInstance) containerInstance._removeAriaLabelledBy(this.id());\n }\n}\n\n/** Secondary line beneath the dialog title — intended for a short description. */\n@Directive({\n selector: '[twDialogSubtitle], tw-dialog-subtitle',\n host: {\n class: 'text-sm text-fg-muted',\n },\n})\nexport class DialogSubtitleDirective {}\n\n/**\n * Dialog description. Registers its ID with the container's `aria-describedby`\n * queue so screen readers announce the descriptive paragraph after the title.\n * Mirrors {@link DialogTitleDirective} but for `aria-describedby`.\n */\n@Directive({\n selector: '[twDialogDescription], tw-dialog-description',\n host: {\n '[id]': 'id()',\n },\n})\nexport class DialogDescriptionDirective implements OnInit, OnDestroy {\n private readonly generatedId = inject(_IdGenerator).getId('tw-dialog-description-');\n private readonly dialogRef = inject<TwDialogRef<unknown, unknown>>(TwDialogRef, {\n optional: true,\n });\n /** Custom id for the description element. Defaults to a generated unique id. */\n readonly id = input<string>(this.generatedId);\n\n ngOnInit(): void {\n const containerInstance = this.dialogRef?.containerInstance;\n if (containerInstance) containerInstance._addAriaDescribedBy(this.id());\n }\n\n ngOnDestroy(): void {\n const containerInstance = this.dialogRef?.containerInstance;\n if (containerInstance) containerInstance._removeAriaDescribedBy(this.id());\n }\n}\n\n/**\n * Scrollable content region of the dialog. Apply between the header and the\n * actions bar. Inherits CDK's `CdkScrollable` to play nicely with scroll\n * strategies and nested scrollables.\n */\n@Directive({\n selector: '[twDialogContent], tw-dialog-content',\n hostDirectives: [CdkScrollable],\n host: {\n class: 'flex-1 overflow-y-auto px-6 py-4 text-sm text-fg',\n },\n})\nexport class DialogContentDirective {}\n\n/** Horizontal alignment for dialog action buttons. */\nexport type DialogActionsAlign = 'start' | 'center' | 'end';\n\n/**\n * Bottom action bar of a dialog. Use inside the dialog content or template to\n * host Cancel/Confirm buttons. Stays pinned below scrollable content.\n */\n@Directive({\n selector: '[twDialogActions], tw-dialog-actions',\n host: {\n '[class]': 'classes()',\n },\n})\nexport class DialogActionsDirective {\n /** Horizontal alignment of the action buttons. Defaults to `'end'`. */\n readonly align = input<DialogActionsAlign>('end');\n\n protected readonly classes = computed(() => {\n const align = this.align();\n const justify =\n align === 'start' ? 'justify-start' : align === 'center' ? 'justify-center' : 'justify-end';\n return `flex flex-wrap items-center gap-2 px-6 py-4 border-t border-border-muted ${justify}`;\n });\n}\n\n/**\n * Closes the enclosing dialog when the host button is clicked. Provide a\n * `[twDialogClose]` value to pass a result to `afterClosed()` subscribers.\n */\n@Directive({\n selector: '[twDialogClose]',\n host: {\n '(click)': 'onClick()',\n '[attr.type]': 'type()',\n },\n})\nexport class DialogCloseDirective {\n /** Value passed to `afterClosed()` when the button is clicked. Defaults to `undefined`. */\n readonly twDialogClose = input<unknown>(undefined);\n\n /** Native button `type`. Defaults to `'button'` to avoid accidental form submission. */\n readonly type = input<'button' | 'submit' | 'reset'>('button');\n\n private readonly dialogRef = inject<TwDialogRef<unknown, unknown>>(TwDialogRef, {\n optional: true,\n });\n\n protected onClick(): void {\n this.dialogRef?.close(this.twDialogClose());\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["CdkDialogConfig"],"mappings":";;;;;;;;;AAuBA;;;;;AAKG;AACG,MAAO,cAAyC,SAAQA,YAAqB,CAAA;;IAEjF,IAAI,GAAkB,IAAI;;IAG1B,sBAAsB,GAAY,GAAG;AAErC;;;;AAIG;IACH,qBAAqB,GAAY,GAAG;;IAGpC,cAAc,GAA4B,OAAO;;IAGxC,QAAQ,GAAqB,oBAAoB;AAE1D;;;;;AAKG;IACM,SAAS,GAAa,IAAI;;IAG1B,YAAY,GAAa,KAAK;;IAG9B,SAAS,GAAuB,gBAAgB;;IAGhD,YAAY,GAA0B,IAAI;;IAG1C,WAAW,GAAa,IAAI;;IAG5B,iBAAiB,GAAa,IAAI;AAC5C;AAED;MACa,cAAc,GAAG,IAAI,cAAc,CAAU,gBAAgB;AAE1E;MACa,yBAAyB,GAAG,IAAI,cAAc,CACzD,2BAA2B;;ACtE7B;;;;;;;;;;;AAWG;MACU,WAAW,CAAA;AAsCW,IAAA,MAAA;;AApCxB,IAAA,EAAE;;AAGF,IAAA,KAAK;;AAGd,IAAA,YAAY;IAEK,WAAW,GAAG,MAAM,CAAc,SAAS;oFAAC;AAC5C,IAAA,kBAAkB,GAAG,IAAI,aAAa,CAAO,CAAC,CAAC;AAC/C,IAAA,mBAAmB,GAAG,IAAI,aAAa,CAAgB,CAAC,CAAC;AACzD,IAAA,kBAAkB,GAAG,IAAI,aAAa,CAAgB,CAAC,CAAC;;;;AAIxD,IAAA,oBAAoB,GAAG,IAAI,OAAO,EAAc;AAChD,IAAA,oBAAoB,GAAG,IAAI,OAAO,EAAiB;IAE5D,MAAM,GAA8B,IAAI;IACxC,SAAS,GAA2B,IAAI;IAExC,sBAAsB,GAAa,IAAI;IACvC,iBAAiB,GAA2B,IAAI;AAChD,IAAA,qBAAqB;AACZ,IAAA,qBAAqB,GAAG,IAAI,OAAO,CAAW,CAAC,OAAO,KAAI;AACzE,QAAA,IAAI,CAAC,qBAAqB,GAAG,OAAO;AACtC,IAAA,CAAC,CAAC;;IAGe,gBAAgB,GAAa,EAAE;IAC/B,mBAAmB,GAAa,EAAE;IAC3C,WAAW,GAA8C,IAAI;AAE7D,IAAA,aAAa;AACb,IAAA,gBAAgB;IAExB,WAAA,CAAY,EAAU,EAAW,MAAkC,EAAA;QAAlC,IAAA,CAAA,MAAM,GAAN,MAAM;AACrC,QAAA,IAAI,CAAC,EAAE,GAAG,EAAE;AACZ,QAAA,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY;QACvC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE;IAC5C;AAEA;;;;;;;;;AASG;AACH,IAAA,IAAI,iBAAiB,GAAA;QACnB,OAAO,IAAI,CAAC,SAAS;IACvB;AAEA;;;;;AAKG;IACH,OAAO,CAAC,MAA0B,EAAE,SAA0B,EAAA;AAC5D,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM;AACpB,QAAA,IAAI,CAAC,SAAS,GAAG,SAAS;;QAG1B,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,oBAAoB,CAAC;QACzD,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,oBAAoB,CAAC;AAEzD,QAAA,MAAM,CAAC,aAAa,CAAC,iBAAiB,CAAC;AACvC,QAAA,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,gBAAgB;AAAE,YAAA,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC;AAClE,QAAA,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,mBAAmB;AAAE,YAAA,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC;QACxE,IAAI,IAAI,CAAC,WAAW;AAAE,YAAA,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AACjF,QAAA,IAAI,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC;AAChC,QAAA,IAAI,CAAC,mBAAmB,CAAC,MAAM,GAAG,CAAC;AACnC,QAAA,IAAI,CAAC,WAAW,GAAG,IAAI;AAEvB,QAAA,MAAM,gBAAgB,GAAG,SAAS,CAAC,qBAAqB;QAExD;AACG,aAAA,IAAI,CACH,MAAM,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC,EACzC,IAAI,CAAC,CAAC,CAAC;aAER,SAAS,CAAC,MAAK;AACd,YAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC;AAC5B,YAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE;AAC9B,YAAA,IAAI,CAAC,kBAAkB,CAAC,QAAQ,EAAE;AACpC,QAAA,CAAC,CAAC;;;;QAKJ;AACG,aAAA,IAAI,CACH,MAAM,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,EAC3C,IAAI,CAAC,CAAC,CAAC;aAER,SAAS,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QAEtC,MAAM,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,SAAS,CAAC,MAAK;AAC7C,YAAA,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,QAAQ,EAAE;gBACnC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC;AACjD,gBAAA,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE;gBACnC,IAAI,CAAC,WAAW,EAAE;YACpB;AACF,QAAA,CAAC,CAAC;AAEF,QAAA,KAAK,CACH,MAAM,CAAC,aAAa,EACpB,MAAM,CAAC,aAAa,CAAC,IAAI,CACvB,MAAM,CACJ,CAAC,KAAK,KAAK,KAAK,CAAC,OAAO,KAAK,MAAM,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CACpF,CACF,CACF,CAAC,SAAS,CAAC,CAAC,KAAK,KAAI;YACpB,IAAI,IAAI,CAAC,YAAY;gBAAE;YACvB,KAAK,CAAC,cAAc,EAAE;AACtB,YAAA,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;AACvE,QAAA,CAAC,CAAC;IACJ;;IAGA,aAAa,CAAC,QAAkB,EAAE,GAA2B,EAAA;AAC3D,QAAA,IAAI,CAAC,sBAAsB,GAAG,QAAQ;AACtC,QAAA,IAAI,CAAC,iBAAiB,GAAG,GAAG;AAC5B,QAAA,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC;IACtC;AAEA;;;;;;;;;;;;;;AAcG;IACH,kBAAkB,GAAA;QAChB,OAAO,IAAI,CAAC,qBAAqB;IACnC;;AAGA,IAAA,IAAI,iBAAiB,GAAA;QACnB,OAAO,IAAI,CAAC,sBAAsB;IACpC;;AAGA,IAAA,IAAI,YAAY,GAAA;QACd,OAAO,IAAI,CAAC,iBAAiB;IAC/B;AAEA;;;AAGG;AACH,IAAA,KAAK,CAAC,MAAU,EAAA;AACd,QAAA,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,MAAM,CAAC;IACzC;;IAGA,WAAW,GAAA;AACT,QAAA,OAAO,IAAI,CAAC,kBAAkB,CAAC,YAAY,EAAE;IAC/C;;IAGA,YAAY,GAAA;AACV,QAAA,OAAO,IAAI,CAAC,mBAAmB,CAAC,YAAY,EAAE;IAChD;;IAGA,WAAW,GAAA;AACT,QAAA,OAAO,IAAI,CAAC,kBAAkB,CAAC,YAAY,EAAE;IAC/C;;IAGA,aAAa,GAAA;AACX,QAAA,OAAO,IAAI,CAAC,oBAAoB,CAAC,YAAY,EAAE;IACjD;;IAGA,aAAa,GAAA;AACX,QAAA,OAAO,IAAI,CAAC,oBAAoB,CAAC,YAAY,EAAE;IACjD;;AAGA,IAAA,UAAU,CAAC,KAAA,GAAyB,EAAE,EAAE,SAA0B,EAAE,EAAA;AAClE,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE;YACf,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC;QACvC;aAAO;YACL,IAAI,CAAC,WAAW,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC;QACpC;AACA,QAAA,OAAO,IAAI;IACb;;AAGA,IAAA,aAAa,CAAC,OAA0B,EAAA;AACtC,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE;AACf,YAAA,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC;QACpC;aAAO;YACL,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;QAC/E;AACA,QAAA,OAAO,IAAI;IACb;;AAGA,IAAA,gBAAgB,CAAC,OAA0B,EAAA;AACzC,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE;AACf,YAAA,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC;QACvC;aAAO;YACL,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;QAClF;AACA,QAAA,OAAO,IAAI;IACb;IAEQ,eAAe,CAAC,MAAmB,EAAE,MAAU,EAAA;AACrD,QAAA,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,SAAS,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,QAAQ;YAAE;AAEzE,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc;AAC5C,QAAA,IACE,SAAS;AACT,YAAA,CAAC,SAAS,CACR,MAAM,EACN,IAAI,CAAC,MAAoD,EACzD,IAAI,CAAC,sBAAsB,CAC5B,EACD;YACA;QACF;AAEA,QAAA,IAAI,CAAC,aAAa,GAAG,MAAM;AAC3B,QAAA,IAAI,CAAC,gBAAgB,GAAG,MAAM;AAC9B,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC;AAE/B,QAAA,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC;AACrC,QAAA,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE;AAEnC,QAAA,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;;;;YAIhB,IAAI,CAAC,WAAW,EAAE;YAClB;QACF;AAEA,QAAA,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE;AACvC,QAAA,IAAI,CAAC,SAAU,CAAC,mBAAmB,EAAE;IACvC;IAEQ,WAAW,GAAA;AACjB,QAAA,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,QAAQ;YAAE;AACrC,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC;QAE9B,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC;AAChD,QAAA,IAAI,CAAC,kBAAkB,CAAC,QAAQ,EAAE;;AAGlC,QAAA,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC;AAChC,QAAA,IAAI,CAAC,oBAAoB,CAAC,QAAQ,EAAE;AACpC,QAAA,IAAI,CAAC,oBAAoB,CAAC,QAAQ,EAAE;AAEpC,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE,iBAAiB,EAAE;AAClC,YAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC/E;AAEA,QAAA,IAAI,CAAC,sBAAsB,GAAG,IAAI;IACpC;AACD;;AChRD,IAAI,YAAY,GAAG,CAAC;AAEpB,SAAS,gBAAgB,GAAA;AACvB,IAAA,OAAO,CAAA,UAAA,EAAa,EAAE,YAAY,CAAA,CAAE;AACtC;AAEA;;;;;;;;;;;;AAYG;MAEU,QAAQ,CAAA;AACF,IAAA,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;AAC3B,IAAA,cAAc,GAAG,MAAM,CAAC,yBAAyB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE;AAC5E,IAAA,YAAY,GAAG,MAAM,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;IAG5E,eAAe,GAAqD,IAAI;IACxE,SAAS,GAAG,KAAK;IAER,sBAAsB,GAAG,MAAM,CAA2C,EAAE;+FAAC;AAC7E,IAAA,kBAAkB,GAAG,IAAI,OAAO,EAAiC;AACjE,IAAA,qBAAqB,GAAG,IAAI,OAAO,EAAQ;;IAGnD,WAAW,GAAqD,IAAI,CAAC;AAC5E,UAAE,IAAI,CAAC,YAAY,CAAC;AACpB,UAAE,IAAI,CAAC,sBAAsB,CAAC,UAAU,EAAE;;IAGnC,WAAW,GAA8C,IAAI,CAAC;AACrE,UAAE,IAAI,CAAC,YAAY,CAAC;AACpB,UAAE,IAAI,CAAC,kBAAkB,CAAC,YAAY,EAAE;AAE1C;;;AAGG;IACM,cAAc,GAAqB,KAAK,CAAC,MAChD,IAAI,CAAC,WAAW,EAAE,CAAC;AACjB,UAAE,IAAI,CAAC,uBAAuB;AAC9B,UAAE,IAAI,CAAC,uBAAuB,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,SAAiB,CAAC,CAAC,CACtE;AAED;;;;;AAKG;IACH,IAAI,CACF,OAA0C,EAC1C,MAA6B,EAAA;QAE7B,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAO,MAAM,CAAC;QAC/C,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,IAAI,gBAAgB,EAAE;AAC1C,QAAA,MAAM,CAAC,EAAE,GAAG,EAAE;;;;AAKd,QAAA,IAAI,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,EAAE;AAC1B,YAAA,MAAM,IAAI,KAAK,CAAC,mBAAmB,EAAE,CAAA,+CAAA,CAAiD,CAAC;QACzF;QAEA,MAAM,KAAK,GAAG,IAAI,WAAW,CAAO,EAAE,EAAE,MAA+C,CAAC;AAExF,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,IAAI,IAAI;AACvC,QAAA,KAAK,CAAC,YAAY,CAAC,KAAiD,CAAC;AACrE,QAAA,KAAK,CAAC,WAAW,EAAE,CAAC,SAAS,CAAC,MAAK;AACjC,YAAA,KAAK,CAAC,UAAU,CAAC,KAAiD,CAAC;AACrE,QAAA,CAAC,CAAC;QAEF,KAAK,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC;AAEjD,QAAA,OAAO,KAAK;IACd;;IAGA,QAAQ,GAAA;QACN,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;AACvC,QAAA,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;AAAE,YAAA,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE;IAClE;;AAGA,IAAA,aAAa,CAA2B,EAAU,EAAA;AAChD,QAAA,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,EAAE,KAAK,EAAE,CAAkC;IAC/F;IAEA,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,SAAS,GAAG,IAAI;QACrB,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,sBAAsB,EAAE,CAAC;AAClD,QAAA,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;AAAE,YAAA,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE;AAChE,QAAA,IAAI,CAAC,kBAAkB,CAAC,QAAQ,EAAE;AAClC,QAAA,IAAI,CAAC,qBAAqB,CAAC,QAAQ,EAAE;IACvC;AAEA;;;AAGG;AACH,IAAA,MAAM,aAAa,GAAA;AACjB,QAAA,MAAM,IAAI,CAAC,YAAY,EAAE;AACzB,QAAA,MAAM,OAAO,CAAC,OAAO,EAAE;IACzB;AAEA;;;;AAIG;AACK,IAAA,MAAM,eAAe,CAC3B,OAA0C,EAC1C,MAA4B,EAC5B,KAAwB,EAAA;AAExB,QAAA,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE;AAC9C,QAAA,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,SAAS;YAAE;;;AAGrC,QAAA,IAAI,KAAK,CAAC,KAAK,EAAE,KAAK,QAAQ;YAAE;QAChC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC;IACrD;IAEQ,YAAY,GAAA;AAClB,QAAA,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE;AACzB,YAAA,IAAI,CAAC,eAAe,GAAG,OAAO,sDAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,kBAAkB,EAAE,KAC7E,IAAI,CAAC,SAAS,GAAG,IAAI,GAAG,kBAAkB,CAC3C;QACH;QACA,OAAO,IAAI,CAAC,eAAe;IAC7B;AAEQ,IAAA,YAAY,CAAC,GAAkC,EAAA;AACrD,QAAA,IAAI,IAAI,CAAC,YAAY,EAAE;AACrB,YAAA,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,GAAG,CAAC;QACrC;aAAO;AACL,YAAA,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC;AAC5D,YAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC;QACnC;IACF;AAEQ,IAAA,UAAU,CAAC,GAAkC,EAAA;AACnD,QAAA,IAAI,IAAI,CAAC,YAAY,EAAE;AACrB,YAAA,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC;QACnC;aAAO;YACL,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC;YAC3E,IAAI,IAAI,CAAC,sBAAsB,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE;AAC9C,gBAAA,IAAI,CAAC,qBAAqB,CAAC,IAAI,EAAE;YACnC;QACF;IACF;IAEQ,uBAAuB,GAAA;QAC7B,OAAO,IAAI,CAAC;AACV,cAAE,IAAI,CAAC,YAAY,CAAC,uBAAuB;AAC3C,cAAE,IAAI,CAAC,qBAAqB;IAChC;AAEQ,IAAA,aAAa,CAAO,MAAwC,EAAA;AAClE,QAAA,MAAM,MAAM,GAAG,IAAI,cAAc,EAAQ;QACzC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC;AAClD,QAAA,OAAO,MAAM;IACf;uGAxJW,QAAQ,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;2GAAR,QAAQ,EAAA,CAAA;;2FAAR,QAAQ,EAAA,UAAA,EAAA,CAAA;kBADpB;;AA4JD;;;;;;;;AAQG;AACG,SAAU,eAAe,CAC7B,cAAwC,EAAA;AAExC,IAAA,MAAM,SAAS,GAAe,CAAC,QAAQ,CAAC;IACxC,IAAI,cAAc,EAAE;AAClB,QAAA,SAAS,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,yBAAyB,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC;IAClF;AACA,IAAA,OAAO,wBAAwB,CAAC,SAAS,CAAC;AAC5C;;AC3MA;;;;AAIG;MAOU,qBAAqB,CAAA;uGAArB,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAArB,qBAAqB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,oCAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,uCAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAArB,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBANjC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,oCAAoC;AAC9C,oBAAA,IAAI,EAAE;AACJ,wBAAA,KAAK,EAAE,uCAAuC;AAC/C,qBAAA;AACF,iBAAA;;AAGD;AACA;AACA,MAAM,kBAAkB,GAA4B;AAClD,IAAA,OAAO,EAAE,mCAAmC;AAC5C,IAAA,SAAS,EAAE,uCAAuC;AAClD,IAAA,MAAM,EAAE,iCAAiC;AACzC,IAAA,OAAO,EAAE,mCAAmC;AAC5C,IAAA,IAAI,EAAE,6BAA6B;AACnC,IAAA,OAAO,EAAE,mCAAmC;AAC5C,IAAA,OAAO,EAAE,mCAAmC;AAC5C,IAAA,KAAK,EAAE,+BAA+B;CACvC;AAED;;;AAGG;MAOU,mBAAmB,CAAA;;IAErB,KAAK,GAAG,KAAK,CAAsB,SAAS;8EAAC;AAEnC,IAAA,OAAO,GAAG,QAAQ,CAAC,MAAK;QACzC,MAAM,IAAI,GAAG,gEAAgE;AAC7E,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE;AAC1B,QAAA,OAAO,KAAK,GAAG,CAAA,EAAG,IAAI,IAAI,kBAAkB,CAAC,KAAK,CAAC,EAAE,GAAG,CAAA,EAAG,IAAI,2BAA2B;IAC5F,CAAC;gFAAC;uGARS,mBAAmB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAnB,mBAAmB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,OAAA,EAAA,WAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAnB,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAN/B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,gBAAgB;AAC1B,oBAAA,IAAI,EAAE;AACJ,wBAAA,SAAS,EAAE,WAAW;AACvB,qBAAA;AACF,iBAAA;;AAYD;;;AAGG;MAQU,oBAAoB,CAAA;IACd,WAAW,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC;AAC5D,IAAA,SAAS,GAAG,MAAM,CAAgC,WAAW,EAAE;AAC9E,QAAA,QAAQ,EAAE,IAAI;AACf,KAAA,CAAC;;AAGO,IAAA,EAAE,GAAG,KAAK,CAAS,IAAI,CAAC,WAAW;2EAAC;IAE7C,QAAQ,GAAA;AACN,QAAA,MAAM,iBAAiB,GAAG,IAAI,CAAC,SAAS,EAAE,iBAAiB;AAC3D,QAAA,IAAI,iBAAiB;YAAE,iBAAiB,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;IACxE;IAEA,WAAW,GAAA;AACT,QAAA,MAAM,iBAAiB,GAAG,IAAI,CAAC,SAAS,EAAE,iBAAiB;AAC3D,QAAA,IAAI,iBAAiB;YAAE,iBAAiB,CAAC,qBAAqB,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;IAC3E;uGAjBW,oBAAoB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAApB,oBAAoB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,kCAAA,EAAA,MAAA,EAAA,EAAA,EAAA,EAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,cAAA,EAAA,+BAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAApB,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBAPhC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,kCAAkC;AAC5C,oBAAA,IAAI,EAAE;AACJ,wBAAA,KAAK,EAAE,+BAA+B;AACtC,wBAAA,MAAM,EAAE,MAAM;AACf,qBAAA;AACF,iBAAA;;AAqBD;MAOa,uBAAuB,CAAA;uGAAvB,uBAAuB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAvB,uBAAuB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,wCAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,uBAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAvB,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBANnC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,wCAAwC;AAClD,oBAAA,IAAI,EAAE;AACJ,wBAAA,KAAK,EAAE,uBAAuB;AAC/B,qBAAA;AACF,iBAAA;;AAGD;;;;AAIG;MAOU,0BAA0B,CAAA;IACpB,WAAW,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,wBAAwB,CAAC;AAClE,IAAA,SAAS,GAAG,MAAM,CAAgC,WAAW,EAAE;AAC9E,QAAA,QAAQ,EAAE,IAAI;AACf,KAAA,CAAC;;AAEO,IAAA,EAAE,GAAG,KAAK,CAAS,IAAI,CAAC,WAAW;2EAAC;IAE7C,QAAQ,GAAA;AACN,QAAA,MAAM,iBAAiB,GAAG,IAAI,CAAC,SAAS,EAAE,iBAAiB;AAC3D,QAAA,IAAI,iBAAiB;YAAE,iBAAiB,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;IACzE;IAEA,WAAW,GAAA;AACT,QAAA,MAAM,iBAAiB,GAAG,IAAI,CAAC,SAAS,EAAE,iBAAiB;AAC3D,QAAA,IAAI,iBAAiB;YAAE,iBAAiB,CAAC,sBAAsB,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;IAC5E;uGAhBW,0BAA0B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAA1B,0BAA0B,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,8CAAA,EAAA,MAAA,EAAA,EAAA,EAAA,EAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAA1B,0BAA0B,EAAA,UAAA,EAAA,CAAA;kBANtC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,8CAA8C;AACxD,oBAAA,IAAI,EAAE;AACJ,wBAAA,MAAM,EAAE,MAAM;AACf,qBAAA;AACF,iBAAA;;AAoBD;;;;AAIG;MAQU,sBAAsB,CAAA;uGAAtB,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAtB,sBAAsB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,sCAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,kDAAA,EAAA,EAAA,cAAA,EAAA,CAAA,EAAA,SAAA,EAAA,EAAA,CAAA,aAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAtB,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBAPlC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,sCAAsC;oBAChD,cAAc,EAAE,CAAC,aAAa,CAAC;AAC/B,oBAAA,IAAI,EAAE;AACJ,wBAAA,KAAK,EAAE,kDAAkD;AAC1D,qBAAA;AACF,iBAAA;;AAMD;;;AAGG;MAOU,sBAAsB,CAAA;;IAExB,KAAK,GAAG,KAAK,CAAqB,KAAK;8EAAC;AAE9B,IAAA,OAAO,GAAG,QAAQ,CAAC,MAAK;AACzC,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE;QAC1B,MAAM,OAAO,GACX,KAAK,KAAK,OAAO,GAAG,eAAe,GAAG,KAAK,KAAK,QAAQ,GAAG,gBAAgB,GAAG,aAAa;QAC7F,OAAO,CAAA,yEAAA,EAA4E,OAAO,CAAA,CAAE;IAC9F,CAAC;gFAAC;uGATS,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAtB,sBAAsB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,sCAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,OAAA,EAAA,WAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAtB,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBANlC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,sCAAsC;AAChD,oBAAA,IAAI,EAAE;AACJ,wBAAA,SAAS,EAAE,WAAW;AACvB,qBAAA;AACF,iBAAA;;AAaD;;;AAGG;MAQU,oBAAoB,CAAA;;IAEtB,aAAa,GAAG,KAAK,CAAU,SAAS;sFAAC;;IAGzC,IAAI,GAAG,KAAK,CAAgC,QAAQ;6EAAC;AAE7C,IAAA,SAAS,GAAG,MAAM,CAAgC,WAAW,EAAE;AAC9E,QAAA,QAAQ,EAAE,IAAI;AACf,KAAA,CAAC;IAEQ,OAAO,GAAA;QACf,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;IAC7C;uGAbW,oBAAoB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAApB,oBAAoB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,EAAA,aAAA,EAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,UAAA,EAAA,eAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,OAAA,EAAA,WAAA,EAAA,EAAA,UAAA,EAAA,EAAA,WAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAApB,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBAPhC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,iBAAiB;AAC3B,oBAAA,IAAI,EAAE;AACJ,wBAAA,SAAS,EAAE,WAAW;AACtB,wBAAA,aAAa,EAAE,QAAQ;AACxB,qBAAA;AACF,iBAAA;;;ACnLD;;AAEG;;;;"}
@@ -277,7 +277,7 @@ class EmptyStateComponent {
277
277
  }
278
278
 
279
279
  <ng-content select="[twEmptyStateActions]" />
280
- `, isInline: true, dependencies: [{ kind: "component", type: IconComponent, selector: "tw-icon", inputs: ["name", "img", "color", "size", "ariaLabel", "svg"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
280
+ `, isInline: true, dependencies: [{ kind: "component", type: IconComponent, selector: "tw-icon", inputs: ["name", "img", "color", "size", "aria-label", "svg"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
281
281
  }
282
282
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: EmptyStateComponent, decorators: [{
283
283
  type: Component,
@@ -1 +1 @@
1
- {"version":3,"file":"cdevhub-ngx-tw-empty-state.mjs","sources":["../../../projects/ngx-tw/empty-state/empty-state.ts","../../../projects/ngx-tw/empty-state/cdevhub-ngx-tw-empty-state.ts"],"sourcesContent":["import { NgTemplateOutlet } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n Directive,\n inject,\n input,\n TemplateRef,\n} from '@angular/core';\nimport { tv } from 'tailwind-variants';\nimport type { TwSize } from '@cdevhub/ngx-tw/core';\nimport { IconComponent } from '@cdevhub/ngx-tw/icon';\n\n/** Layout style of the empty state. */\nexport type EmptyStateVariant = 'centered' | 'inline';\n\n/** Heading level for the title element. Matches native `<h1>`–`<h6>`. */\nexport type EmptyStateTitleLevel = 1 | 2 | 3 | 4 | 5 | 6;\n\nconst emptyState = tv({\n slots: {\n root: 'text-fg',\n iconWrapper: 'text-fg-subtle shrink-0',\n // Title typography is constant across all sizes per CLAUDE.md typography\n // rules: `text-base` is permitted only for the codified tw-item lg\n // exception. Consumers wanting a larger heading project\n // `*twEmptyStateTitle` with their own typography.\n title: 'text-sm font-semibold text-fg',\n description: 'text-fg-muted',\n actions: 'flex flex-wrap items-center gap-2',\n },\n variants: {\n variant: {\n centered: {\n root: 'flex flex-col items-center justify-center text-center',\n actions: 'justify-center',\n },\n inline: {\n root: 'flex flex-row items-center text-left',\n actions: 'ml-auto',\n },\n },\n size: {\n xs: {\n root: 'p-2 gap-1.5',\n description: 'text-xs',\n },\n sm: {\n root: 'p-3 gap-2',\n description: 'text-sm',\n },\n md: {\n root: 'p-4 gap-3',\n description: 'text-sm',\n },\n lg: {\n root: 'p-6 gap-3',\n description: 'text-sm',\n },\n xl: {\n root: 'p-8 gap-3',\n description: 'text-sm',\n },\n },\n },\n compoundVariants: [\n // Inline variant tightens vertical padding regardless of size so the\n // empty state can act as a table row without dominating row height. The\n // horizontal padding still comes from the size's root entry.\n //\n // The py-1.5 → py-2 → py-3 → py-4 → py-5 progression is design-specified\n // off the canonical inline-padding scale: each step keeps the inline\n // empty state visually distinct from adjacent rows without jumping a\n // full container-padding step (py-6 / py-8) and crowding the row.\n // py-1.5 matches the sm inline-padding density; py-5 is the in-between\n // step before xl rows take a container-padding step.\n { variant: 'inline', size: 'xs', class: { root: 'py-1.5 gap-2' } },\n { variant: 'inline', size: 'sm', class: { root: 'py-2 gap-3' } },\n { variant: 'inline', size: 'md', class: { root: 'py-3 gap-3' } },\n { variant: 'inline', size: 'lg', class: { root: 'py-4 gap-3' } },\n { variant: 'inline', size: 'xl', class: { root: 'py-5 gap-3' } },\n ],\n defaultVariants: {\n variant: 'centered',\n size: 'md',\n },\n}, {\n twMerge: true,\n});\n\n/**\n * Icon-slot marker. Project an icon element with `twEmptyStateIcon` to\n * replace the fallback `<tw-icon name=\"inbox\">`.\n *\n * @example\n * ```html\n * <tw-empty-state>\n * <tw-icon twEmptyStateIcon name=\"search\" />\n * </tw-empty-state>\n * ```\n */\n@Directive({\n selector: '[twEmptyStateIcon]',\n})\nexport class EmptyStateIconDirective {}\n\n/**\n * Structural title slot. Captures a `TemplateRef` so the heading can be\n * rendered into the dynamic `<h1>`–`<h6>` wrapper at runtime.\n *\n * @example\n * ```html\n * <tw-empty-state>\n * <span *twEmptyStateTitle>No results <tw-badge>0</tw-badge></span>\n * </tw-empty-state>\n * ```\n */\n@Directive({\n selector: '[twEmptyStateTitle]',\n})\nexport class EmptyStateTitleDirective {\n readonly templateRef = inject<TemplateRef<unknown>>(TemplateRef);\n}\n\n/**\n * Structural description slot. Captures a `TemplateRef` so the content can\n * be rendered into the `<p>` wrapper.\n *\n * @example\n * ```html\n * <tw-empty-state>\n * <span *twEmptyStateDescription>Try a <a href=\"…\">different search</a>.</span>\n * </tw-empty-state>\n * ```\n */\n@Directive({\n selector: '[twEmptyStateDescription]',\n})\nexport class EmptyStateDescriptionDirective {\n readonly templateRef = inject<TemplateRef<unknown>>(TemplateRef);\n}\n\n/** Actions-slot directive. Carries the actions row classes (`flex gap-2` etc.) on its host. */\n@Directive({\n selector: '[twEmptyStateActions]',\n host: {\n '[class]': 'classes()',\n },\n})\nexport class EmptyStateActionsDirective {\n private readonly emptyStateRef = inject(EmptyStateComponent);\n readonly classes = this.emptyStateRef.actionsClasses;\n}\n\n/**\n * Zero-data layout primitive. Renders an icon, title, description, and\n * actions for surfaces that have nothing to display.\n *\n * The component is intentionally neutral — accent comes from projected\n * action buttons. It does not announce itself: consumers that want a live\n * announcement (e.g. \"no search results found\") wrap the component with\n * `<div role=\"status\" aria-live=\"polite\">…</div>` themselves.\n */\n@Component({\n selector: 'tw-empty-state',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [IconComponent, NgTemplateOutlet],\n host: {\n '[class]': 'rootClasses()',\n },\n template: `\n <ng-template #titleBody>\n @if (titleSlot(); as slot) {\n <ng-container [ngTemplateOutlet]=\"slot.templateRef\" />\n } @else {\n {{ title() }}\n }\n </ng-template>\n\n <ng-template #descriptionBody>\n @if (descriptionSlot(); as slot) {\n <ng-container [ngTemplateOutlet]=\"slot.templateRef\" />\n } @else {\n {{ description() }}\n }\n </ng-template>\n\n <ng-template #titleBlock>\n @switch (titleLevel()) {\n @case (1) { <h1 [class]=\"titleClasses()\"><ng-container [ngTemplateOutlet]=\"titleBody\" /></h1> }\n @case (2) { <h2 [class]=\"titleClasses()\"><ng-container [ngTemplateOutlet]=\"titleBody\" /></h2> }\n @case (4) { <h4 [class]=\"titleClasses()\"><ng-container [ngTemplateOutlet]=\"titleBody\" /></h4> }\n @case (5) { <h5 [class]=\"titleClasses()\"><ng-container [ngTemplateOutlet]=\"titleBody\" /></h5> }\n @case (6) { <h6 [class]=\"titleClasses()\"><ng-container [ngTemplateOutlet]=\"titleBody\" /></h6> }\n @default { <h3 [class]=\"titleClasses()\"><ng-container [ngTemplateOutlet]=\"titleBody\" /></h3> }\n }\n </ng-template>\n\n <ng-template #descriptionBlock>\n <p [class]=\"descriptionClasses()\"><ng-container [ngTemplateOutlet]=\"descriptionBody\" /></p>\n </ng-template>\n\n <div [class]=\"iconWrapperClasses()\">\n <ng-content select=\"[twEmptyStateIcon]\">\n <tw-icon name=\"inbox\" [size]=\"iconSize()\" aria-hidden=\"true\" />\n </ng-content>\n </div>\n\n @if (variant() === 'inline' && (hasTitle() || hasDescription())) {\n <div class=\"min-w-0 flex-1\">\n @if (hasTitle()) { <ng-container [ngTemplateOutlet]=\"titleBlock\" /> }\n @if (hasDescription()) { <ng-container [ngTemplateOutlet]=\"descriptionBlock\" /> }\n </div>\n } @else {\n @if (hasTitle()) { <ng-container [ngTemplateOutlet]=\"titleBlock\" /> }\n @if (hasDescription()) { <ng-container [ngTemplateOutlet]=\"descriptionBlock\" /> }\n }\n\n <ng-content select=\"[twEmptyStateActions]\" />\n `,\n})\nexport class EmptyStateComponent {\n /** Controls overall spacing and icon scale. Defaults to `'md'`. */\n readonly size = input<TwSize>('md');\n\n /** Layout style. `'centered'` stacks icon/title/description/actions vertically with center alignment for full-region usage; `'inline'` arranges them horizontally for compact rows. Defaults to `'centered'`. */\n readonly variant = input<EmptyStateVariant>('centered');\n\n /** Primary heading text. Projected `*twEmptyStateTitle` content takes precedence. Defaults to `undefined`. */\n readonly title = input<string>();\n\n /** Secondary descriptive text. Projected `*twEmptyStateDescription` content takes precedence. Defaults to `undefined`. */\n readonly description = input<string>();\n\n /** Heading level used for the title element. Set to match the surrounding document outline. Defaults to `3`. */\n readonly titleLevel = input<EmptyStateTitleLevel>(3);\n\n /** @internal */\n readonly titleSlot = contentChild(EmptyStateTitleDirective);\n /** @internal */\n readonly descriptionSlot = contentChild(EmptyStateDescriptionDirective);\n\n readonly hasTitleSlot = computed(() => !!this.titleSlot());\n readonly hasDescriptionSlot = computed(() => !!this.descriptionSlot());\n\n readonly hasTitle = computed(\n () => this.hasTitleSlot() || !!this.title()?.trim(),\n );\n readonly hasDescription = computed(\n () => this.hasDescriptionSlot() || !!this.description()?.trim(),\n );\n\n /** Size passed to the fallback `<tw-icon>` per CLAUDE.md glyph sub-scale. */\n readonly iconSize = computed<TwSize>(() => {\n const size = this.size();\n if (this.variant() === 'inline') {\n switch (size) {\n case 'xs': return 'xs';\n case 'sm': return 'sm';\n case 'md': return 'md';\n case 'lg': return 'lg';\n case 'xl': return 'lg';\n }\n }\n switch (size) {\n case 'xs': return 'sm';\n case 'sm': return 'md';\n case 'md': return 'xl';\n case 'lg': return 'xl';\n case 'xl': return 'xl';\n }\n });\n\n private readonly variantResult = computed(() =>\n emptyState({ variant: this.variant(), size: this.size() }),\n );\n\n readonly rootClasses = computed(() => this.variantResult().root());\n readonly iconWrapperClasses = computed(() => this.variantResult().iconWrapper());\n readonly titleClasses = computed(() => this.variantResult().title());\n readonly descriptionClasses = computed(() => this.variantResult().description());\n readonly actionsClasses = computed(() => this.variantResult().actions());\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cdevhub-ngx-tw-empty-state.mjs","sources":["../../../projects/ngx-tw/empty-state/empty-state.ts","../../../projects/ngx-tw/empty-state/cdevhub-ngx-tw-empty-state.ts"],"sourcesContent":["import { NgTemplateOutlet } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n Directive,\n inject,\n input,\n TemplateRef,\n} from '@angular/core';\nimport { tv } from 'tailwind-variants';\nimport type { TwSize } from '@cdevhub/ngx-tw/core';\nimport { IconComponent } from '@cdevhub/ngx-tw/icon';\n\n/** Layout style of the empty state. */\nexport type EmptyStateVariant = 'centered' | 'inline';\n\n/** Heading level for the title element. Matches native `<h1>`–`<h6>`. */\nexport type EmptyStateTitleLevel = 1 | 2 | 3 | 4 | 5 | 6;\n\nconst emptyState = tv({\n slots: {\n root: 'text-fg',\n iconWrapper: 'text-fg-subtle shrink-0',\n // Title typography is constant across all sizes per CLAUDE.md typography\n // rules: `text-base` is permitted only for the codified tw-item lg\n // exception. Consumers wanting a larger heading project\n // `*twEmptyStateTitle` with their own typography.\n title: 'text-sm font-semibold text-fg',\n description: 'text-fg-muted',\n actions: 'flex flex-wrap items-center gap-2',\n },\n variants: {\n variant: {\n centered: {\n root: 'flex flex-col items-center justify-center text-center',\n actions: 'justify-center',\n },\n inline: {\n root: 'flex flex-row items-center text-left',\n actions: 'ml-auto',\n },\n },\n size: {\n xs: {\n root: 'p-2 gap-1.5',\n description: 'text-xs',\n },\n sm: {\n root: 'p-3 gap-2',\n description: 'text-sm',\n },\n md: {\n root: 'p-4 gap-3',\n description: 'text-sm',\n },\n lg: {\n root: 'p-6 gap-3',\n description: 'text-sm',\n },\n xl: {\n root: 'p-8 gap-3',\n description: 'text-sm',\n },\n },\n },\n compoundVariants: [\n // Inline variant tightens vertical padding regardless of size so the\n // empty state can act as a table row without dominating row height. The\n // horizontal padding still comes from the size's root entry.\n //\n // The py-1.5 → py-2 → py-3 → py-4 → py-5 progression is design-specified\n // off the canonical inline-padding scale: each step keeps the inline\n // empty state visually distinct from adjacent rows without jumping a\n // full container-padding step (py-6 / py-8) and crowding the row.\n // py-1.5 matches the sm inline-padding density; py-5 is the in-between\n // step before xl rows take a container-padding step.\n { variant: 'inline', size: 'xs', class: { root: 'py-1.5 gap-2' } },\n { variant: 'inline', size: 'sm', class: { root: 'py-2 gap-3' } },\n { variant: 'inline', size: 'md', class: { root: 'py-3 gap-3' } },\n { variant: 'inline', size: 'lg', class: { root: 'py-4 gap-3' } },\n { variant: 'inline', size: 'xl', class: { root: 'py-5 gap-3' } },\n ],\n defaultVariants: {\n variant: 'centered',\n size: 'md',\n },\n}, {\n twMerge: true,\n});\n\n/**\n * Icon-slot marker. Project an icon element with `twEmptyStateIcon` to\n * replace the fallback `<tw-icon name=\"inbox\">`.\n *\n * @example\n * ```html\n * <tw-empty-state>\n * <tw-icon twEmptyStateIcon name=\"search\" />\n * </tw-empty-state>\n * ```\n */\n@Directive({\n selector: '[twEmptyStateIcon]',\n})\nexport class EmptyStateIconDirective {}\n\n/**\n * Structural title slot. Captures a `TemplateRef` so the heading can be\n * rendered into the dynamic `<h1>`–`<h6>` wrapper at runtime.\n *\n * @example\n * ```html\n * <tw-empty-state>\n * <span *twEmptyStateTitle>No results <tw-badge>0</tw-badge></span>\n * </tw-empty-state>\n * ```\n */\n@Directive({\n selector: '[twEmptyStateTitle]',\n})\nexport class EmptyStateTitleDirective {\n readonly templateRef = inject<TemplateRef<unknown>>(TemplateRef);\n}\n\n/**\n * Structural description slot. Captures a `TemplateRef` so the content can\n * be rendered into the `<p>` wrapper.\n *\n * @example\n * ```html\n * <tw-empty-state>\n * <span *twEmptyStateDescription>Try a <a href=\"…\">different search</a>.</span>\n * </tw-empty-state>\n * ```\n */\n@Directive({\n selector: '[twEmptyStateDescription]',\n})\nexport class EmptyStateDescriptionDirective {\n readonly templateRef = inject<TemplateRef<unknown>>(TemplateRef);\n}\n\n/** Actions-slot directive. Carries the actions row classes (`flex gap-2` etc.) on its host. */\n@Directive({\n selector: '[twEmptyStateActions]',\n host: {\n '[class]': 'classes()',\n },\n})\nexport class EmptyStateActionsDirective {\n private readonly emptyStateRef = inject(EmptyStateComponent);\n readonly classes = this.emptyStateRef.actionsClasses;\n}\n\n/**\n * Zero-data layout primitive. Renders an icon, title, description, and\n * actions for surfaces that have nothing to display.\n *\n * The component is intentionally neutral — accent comes from projected\n * action buttons. It does not announce itself: consumers that want a live\n * announcement (e.g. \"no search results found\") wrap the component with\n * `<div role=\"status\" aria-live=\"polite\">…</div>` themselves.\n */\n@Component({\n selector: 'tw-empty-state',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [IconComponent, NgTemplateOutlet],\n host: {\n '[class]': 'rootClasses()',\n },\n template: `\n <ng-template #titleBody>\n @if (titleSlot(); as slot) {\n <ng-container [ngTemplateOutlet]=\"slot.templateRef\" />\n } @else {\n {{ title() }}\n }\n </ng-template>\n\n <ng-template #descriptionBody>\n @if (descriptionSlot(); as slot) {\n <ng-container [ngTemplateOutlet]=\"slot.templateRef\" />\n } @else {\n {{ description() }}\n }\n </ng-template>\n\n <ng-template #titleBlock>\n @switch (titleLevel()) {\n @case (1) { <h1 [class]=\"titleClasses()\"><ng-container [ngTemplateOutlet]=\"titleBody\" /></h1> }\n @case (2) { <h2 [class]=\"titleClasses()\"><ng-container [ngTemplateOutlet]=\"titleBody\" /></h2> }\n @case (4) { <h4 [class]=\"titleClasses()\"><ng-container [ngTemplateOutlet]=\"titleBody\" /></h4> }\n @case (5) { <h5 [class]=\"titleClasses()\"><ng-container [ngTemplateOutlet]=\"titleBody\" /></h5> }\n @case (6) { <h6 [class]=\"titleClasses()\"><ng-container [ngTemplateOutlet]=\"titleBody\" /></h6> }\n @default { <h3 [class]=\"titleClasses()\"><ng-container [ngTemplateOutlet]=\"titleBody\" /></h3> }\n }\n </ng-template>\n\n <ng-template #descriptionBlock>\n <p [class]=\"descriptionClasses()\"><ng-container [ngTemplateOutlet]=\"descriptionBody\" /></p>\n </ng-template>\n\n <div [class]=\"iconWrapperClasses()\">\n <ng-content select=\"[twEmptyStateIcon]\">\n <tw-icon name=\"inbox\" [size]=\"iconSize()\" aria-hidden=\"true\" />\n </ng-content>\n </div>\n\n @if (variant() === 'inline' && (hasTitle() || hasDescription())) {\n <div class=\"min-w-0 flex-1\">\n @if (hasTitle()) { <ng-container [ngTemplateOutlet]=\"titleBlock\" /> }\n @if (hasDescription()) { <ng-container [ngTemplateOutlet]=\"descriptionBlock\" /> }\n </div>\n } @else {\n @if (hasTitle()) { <ng-container [ngTemplateOutlet]=\"titleBlock\" /> }\n @if (hasDescription()) { <ng-container [ngTemplateOutlet]=\"descriptionBlock\" /> }\n }\n\n <ng-content select=\"[twEmptyStateActions]\" />\n `,\n})\nexport class EmptyStateComponent {\n /** Controls overall spacing and icon scale. Defaults to `'md'`. */\n readonly size = input<TwSize>('md');\n\n /** Layout style. `'centered'` stacks icon/title/description/actions vertically with center alignment for full-region usage; `'inline'` arranges them horizontally for compact rows. Defaults to `'centered'`. */\n readonly variant = input<EmptyStateVariant>('centered');\n\n /** Primary heading text. Projected `*twEmptyStateTitle` content takes precedence. Defaults to `undefined`. */\n readonly title = input<string>();\n\n /** Secondary descriptive text. Projected `*twEmptyStateDescription` content takes precedence. Defaults to `undefined`. */\n readonly description = input<string>();\n\n /** Heading level used for the title element. Set to match the surrounding document outline. Defaults to `3`. */\n readonly titleLevel = input<EmptyStateTitleLevel>(3);\n\n /** @internal */\n readonly titleSlot = contentChild(EmptyStateTitleDirective);\n /** @internal */\n readonly descriptionSlot = contentChild(EmptyStateDescriptionDirective);\n\n readonly hasTitleSlot = computed(() => !!this.titleSlot());\n readonly hasDescriptionSlot = computed(() => !!this.descriptionSlot());\n\n readonly hasTitle = computed(\n () => this.hasTitleSlot() || !!this.title()?.trim(),\n );\n readonly hasDescription = computed(\n () => this.hasDescriptionSlot() || !!this.description()?.trim(),\n );\n\n /** Size passed to the fallback `<tw-icon>` per CLAUDE.md glyph sub-scale. */\n readonly iconSize = computed<TwSize>(() => {\n const size = this.size();\n if (this.variant() === 'inline') {\n switch (size) {\n case 'xs': return 'xs';\n case 'sm': return 'sm';\n case 'md': return 'md';\n case 'lg': return 'lg';\n case 'xl': return 'lg';\n }\n }\n switch (size) {\n case 'xs': return 'sm';\n case 'sm': return 'md';\n case 'md': return 'xl';\n case 'lg': return 'xl';\n case 'xl': return 'xl';\n }\n });\n\n private readonly variantResult = computed(() =>\n emptyState({ variant: this.variant(), size: this.size() }),\n );\n\n readonly rootClasses = computed(() => this.variantResult().root());\n readonly iconWrapperClasses = computed(() => this.variantResult().iconWrapper());\n readonly titleClasses = computed(() => this.variantResult().title());\n readonly descriptionClasses = computed(() => this.variantResult().description());\n readonly actionsClasses = computed(() => this.variantResult().actions());\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,149 @@
1
+ import { ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';
2
+
3
+ /**
4
+ * Harness for a single attached file in a `tw-file-upload`'s list.
5
+ *
6
+ * Reach these through {@link FileUploadHarness.getFiles}.
7
+ *
8
+ * Everything here reads the *default* row rendering. A consumer who projects a
9
+ * `*twFileUploadItem` template replaces the row wholesale — including the
10
+ * remove control this harness drives — so {@link getName} and {@link remove}
11
+ * apply only to the built-in row.
12
+ */
13
+ class FileUploadFileHarness extends ComponentHarness {
14
+ static hostSelector = 'ul[role="list"] > li';
15
+ removeButton = this.locatorFor('[data-tw-file-upload-remove]');
16
+ /** Predicate for `locatorFor` / `locatorForAll`. */
17
+ static with(options = {}) {
18
+ return new HarnessPredicate(FileUploadFileHarness, options).addOption('name', options.name, async (h, name) => HarnessPredicate.stringMatches(await h.getName(), name));
19
+ }
20
+ /**
21
+ * The attached file's name, read from the remove control's accessible name
22
+ * (`Remove <name>`). That is the one place the name is exposed through an
23
+ * accessibility contract rather than through presentational markup.
24
+ */
25
+ async getName() {
26
+ const label = (await (await this.removeButton()).getAttribute('aria-label')) ?? '';
27
+ return label.replace(/^Remove /, '');
28
+ }
29
+ /**
30
+ * The row's full rendered text, whitespace-collapsed.
31
+ *
32
+ * The name and the meta line sit in adjacent `<span>`s with only a
33
+ * whitespace-only text node between them, which Angular strips, so they run
34
+ * together here (`notes.txt10 B`). Prefer {@link getName} and
35
+ * {@link getMetaText} for the parts; this is the raw read that still says
36
+ * something about a row rendered from a projected template.
37
+ */
38
+ async getText() {
39
+ return (await (await this.host()).text()).replace(/\s+/g, ' ').trim();
40
+ }
41
+ /**
42
+ * The row's meta line — the formatted size, plus the status and error text
43
+ * once the item leaves `pending` (`10 B`, `10 B · Uploading`,
44
+ * `10 B · Failed — <error>`).
45
+ *
46
+ * This string is the only place per-item status and error surface in the
47
+ * DOM: there is no `data-status` hook, and the status otherwise shows up
48
+ * only in Tailwind classes, which a harness must not read. Derived by
49
+ * subtracting {@link getName} from {@link getText} for the same reason.
50
+ */
51
+ async getMetaText() {
52
+ const text = await this.getText();
53
+ const name = await this.getName();
54
+ return text.startsWith(name) ? text.slice(name.length).trim() : text;
55
+ }
56
+ /**
57
+ * Clicks the row's remove control.
58
+ *
59
+ * The component retargets focus in an `afterNextRender` — deliberately, so
60
+ * that the list has re-rendered before focus moves — so the focus assertion
61
+ * a caller makes after this resolves is the post-render one.
62
+ */
63
+ async remove() {
64
+ await (await this.removeButton()).click();
65
+ await this.waitForTasksOutsideAngular();
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Harness for `tw-file-upload`.
71
+ *
72
+ * ## What this harness deliberately cannot do
73
+ *
74
+ * It cannot attach a file. Selecting a file means populating
75
+ * `HTMLInputElement.files`, which is read-only to script and which CDK's
76
+ * `TestElement` — the whole reason a harness runs unchanged against a real
77
+ * browser — has no operation for. The only way to do it is
78
+ * `Object.defineProperty` on the raw DOM node, which exists solely in the
79
+ * Testbed environment. Exposing that would make the harness silently
80
+ * unusable in every other environment, so attaching stays the caller's job:
81
+ * seed files through the bound form control (`writeValue` takes a `File[]`),
82
+ * or through the component's own API, and use this harness for everything
83
+ * downstream of the attachment.
84
+ *
85
+ * Nothing here needs a CDK overlay, so the ordinary fixture loader is enough.
86
+ *
87
+ * Note where the ARIA lives: the host is a `role="group"`, which ARIA 1.2 does
88
+ * not allow to carry `aria-required` / `aria-invalid`, so both sit on the
89
+ * hidden `<input type="file">` — the element that actually owns the value.
90
+ * {@link isRequired} and {@link isInvalid} read them from there;
91
+ * {@link isDisabled} reads `aria-disabled` from the group, which is allowed.
92
+ */
93
+ class FileUploadHarness extends ComponentHarness {
94
+ static hostSelector = 'tw-file-upload';
95
+ /** The hidden native control. It carries the value-owning ARIA and state. */
96
+ nativeInput = this.locatorFor('input[type="file"]');
97
+ /** Predicate for `locatorFor` / `locatorForAll`. */
98
+ static with(options = {}) {
99
+ return new HarnessPredicate(FileUploadHarness, options)
100
+ .addOption('label', options.label, async (h, label) => HarnessPredicate.stringMatches(await h.getLabel(), label))
101
+ .addOption('disabled', options.disabled, async (h, disabled) => (await h.isDisabled()) === disabled);
102
+ }
103
+ /** The control's accessible name, from `aria-label` when one is set. */
104
+ async getLabel() {
105
+ return (await this.host()).getAttribute('aria-label');
106
+ }
107
+ /** Whether the group reports `aria-disabled="true"`. */
108
+ async isDisabled() {
109
+ return (await (await this.host()).getAttribute('aria-disabled')) === 'true';
110
+ }
111
+ /** Whether the native file input is marked required. */
112
+ async isRequired() {
113
+ return (await this.nativeInput()).getProperty('required');
114
+ }
115
+ /** Whether the native file input reports `aria-invalid="true"`. */
116
+ async isInvalid() {
117
+ return (await (await this.nativeInput()).getAttribute('aria-invalid')) === 'true';
118
+ }
119
+ /**
120
+ * Every attached file, in list order. Returns `[]` when nothing is attached
121
+ * — the list element is always rendered, just empty.
122
+ */
123
+ async getFiles(filters = {}) {
124
+ return this.locatorForAll(FileUploadFileHarness.with(filters))();
125
+ }
126
+ /** The name of every attached file, in list order. */
127
+ async getFileNames() {
128
+ const files = await this.getFiles();
129
+ return Promise.all(files.map((file) => file.getName()));
130
+ }
131
+ /**
132
+ * Removes the first attached file whose name matches. Throws when nothing
133
+ * matches, rather than failing silently.
134
+ */
135
+ async removeFile(name) {
136
+ const matches = await this.getFiles({ name });
137
+ if (matches.length === 0) {
138
+ throw new Error(`FileUploadHarness.removeFile: no attached file matching ${String(name)}.`);
139
+ }
140
+ await matches[0].remove();
141
+ }
142
+ }
143
+
144
+ /**
145
+ * Generated bundle index. Do not edit.
146
+ */
147
+
148
+ export { FileUploadFileHarness, FileUploadHarness };
149
+ //# sourceMappingURL=cdevhub-ngx-tw-file-upload-testing.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cdevhub-ngx-tw-file-upload-testing.mjs","sources":["../../../projects/ngx-tw/file-upload/testing/file-upload-file-harness.ts","../../../projects/ngx-tw/file-upload/testing/file-upload-harness.ts","../../../projects/ngx-tw/file-upload/testing/cdevhub-ngx-tw-file-upload-testing.ts"],"sourcesContent":["import { ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';\nimport type { BaseHarnessFilters } from '@angular/cdk/testing';\n\n/** Filters accepted by `FileUploadFileHarness.with`. */\nexport interface FileUploadFileHarnessFilters extends BaseHarnessFilters {\n /** Match by the attached file's name. */\n name?: string | RegExp;\n}\n\n/**\n * Harness for a single attached file in a `tw-file-upload`'s list.\n *\n * Reach these through {@link FileUploadHarness.getFiles}.\n *\n * Everything here reads the *default* row rendering. A consumer who projects a\n * `*twFileUploadItem` template replaces the row wholesale — including the\n * remove control this harness drives — so {@link getName} and {@link remove}\n * apply only to the built-in row.\n */\nexport class FileUploadFileHarness extends ComponentHarness {\n static hostSelector = 'ul[role=\"list\"] > li';\n\n private readonly removeButton = this.locatorFor('[data-tw-file-upload-remove]');\n\n /** Predicate for `locatorFor` / `locatorForAll`. */\n static with(\n options: FileUploadFileHarnessFilters = {},\n ): HarnessPredicate<FileUploadFileHarness> {\n return new HarnessPredicate(FileUploadFileHarness, options).addOption(\n 'name',\n options.name,\n async (h, name) => HarnessPredicate.stringMatches(await h.getName(), name),\n );\n }\n\n /**\n * The attached file's name, read from the remove control's accessible name\n * (`Remove <name>`). That is the one place the name is exposed through an\n * accessibility contract rather than through presentational markup.\n */\n async getName(): Promise<string> {\n const label = (await (await this.removeButton()).getAttribute('aria-label')) ?? '';\n return label.replace(/^Remove /, '');\n }\n\n /**\n * The row's full rendered text, whitespace-collapsed.\n *\n * The name and the meta line sit in adjacent `<span>`s with only a\n * whitespace-only text node between them, which Angular strips, so they run\n * together here (`notes.txt10 B`). Prefer {@link getName} and\n * {@link getMetaText} for the parts; this is the raw read that still says\n * something about a row rendered from a projected template.\n */\n async getText(): Promise<string> {\n return (await (await this.host()).text()).replace(/\\s+/g, ' ').trim();\n }\n\n /**\n * The row's meta line — the formatted size, plus the status and error text\n * once the item leaves `pending` (`10 B`, `10 B · Uploading`,\n * `10 B · Failed — <error>`).\n *\n * This string is the only place per-item status and error surface in the\n * DOM: there is no `data-status` hook, and the status otherwise shows up\n * only in Tailwind classes, which a harness must not read. Derived by\n * subtracting {@link getName} from {@link getText} for the same reason.\n */\n async getMetaText(): Promise<string> {\n const text = await this.getText();\n const name = await this.getName();\n return text.startsWith(name) ? text.slice(name.length).trim() : text;\n }\n\n /**\n * Clicks the row's remove control.\n *\n * The component retargets focus in an `afterNextRender` — deliberately, so\n * that the list has re-rendered before focus moves — so the focus assertion\n * a caller makes after this resolves is the post-render one.\n */\n async remove(): Promise<void> {\n await (await this.removeButton()).click();\n await this.waitForTasksOutsideAngular();\n }\n}\n","import { ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';\nimport type { BaseHarnessFilters } from '@angular/cdk/testing';\nimport {\n FileUploadFileHarness,\n type FileUploadFileHarnessFilters,\n} from './file-upload-file-harness';\n\n/** Filters accepted by `FileUploadHarness.with`. */\nexport interface FileUploadHarnessFilters extends BaseHarnessFilters {\n /** Match by the control's accessible name (its `aria-label`). */\n label?: string | RegExp;\n /** Match disabled / enabled controls. */\n disabled?: boolean;\n}\n\n/**\n * Harness for `tw-file-upload`.\n *\n * ## What this harness deliberately cannot do\n *\n * It cannot attach a file. Selecting a file means populating\n * `HTMLInputElement.files`, which is read-only to script and which CDK's\n * `TestElement` — the whole reason a harness runs unchanged against a real\n * browser — has no operation for. The only way to do it is\n * `Object.defineProperty` on the raw DOM node, which exists solely in the\n * Testbed environment. Exposing that would make the harness silently\n * unusable in every other environment, so attaching stays the caller's job:\n * seed files through the bound form control (`writeValue` takes a `File[]`),\n * or through the component's own API, and use this harness for everything\n * downstream of the attachment.\n *\n * Nothing here needs a CDK overlay, so the ordinary fixture loader is enough.\n *\n * Note where the ARIA lives: the host is a `role=\"group\"`, which ARIA 1.2 does\n * not allow to carry `aria-required` / `aria-invalid`, so both sit on the\n * hidden `<input type=\"file\">` — the element that actually owns the value.\n * {@link isRequired} and {@link isInvalid} read them from there;\n * {@link isDisabled} reads `aria-disabled` from the group, which is allowed.\n */\nexport class FileUploadHarness extends ComponentHarness {\n static hostSelector = 'tw-file-upload';\n\n /** The hidden native control. It carries the value-owning ARIA and state. */\n private readonly nativeInput = this.locatorFor('input[type=\"file\"]');\n\n /** Predicate for `locatorFor` / `locatorForAll`. */\n static with(\n options: FileUploadHarnessFilters = {},\n ): HarnessPredicate<FileUploadHarness> {\n return new HarnessPredicate(FileUploadHarness, options)\n .addOption('label', options.label, async (h, label) =>\n HarnessPredicate.stringMatches(await h.getLabel(), label),\n )\n .addOption(\n 'disabled',\n options.disabled,\n async (h, disabled) => (await h.isDisabled()) === disabled,\n );\n }\n\n /** The control's accessible name, from `aria-label` when one is set. */\n async getLabel(): Promise<string | null> {\n return (await this.host()).getAttribute('aria-label');\n }\n\n /** Whether the group reports `aria-disabled=\"true\"`. */\n async isDisabled(): Promise<boolean> {\n return (await (await this.host()).getAttribute('aria-disabled')) === 'true';\n }\n\n /** Whether the native file input is marked required. */\n async isRequired(): Promise<boolean> {\n return (await this.nativeInput()).getProperty<boolean>('required');\n }\n\n /** Whether the native file input reports `aria-invalid=\"true\"`. */\n async isInvalid(): Promise<boolean> {\n return (await (await this.nativeInput()).getAttribute('aria-invalid')) === 'true';\n }\n\n /**\n * Every attached file, in list order. Returns `[]` when nothing is attached\n * — the list element is always rendered, just empty.\n */\n async getFiles(\n filters: FileUploadFileHarnessFilters = {},\n ): Promise<FileUploadFileHarness[]> {\n return this.locatorForAll(FileUploadFileHarness.with(filters))();\n }\n\n /** The name of every attached file, in list order. */\n async getFileNames(): Promise<string[]> {\n const files = await this.getFiles();\n return Promise.all(files.map((file) => file.getName()));\n }\n\n /**\n * Removes the first attached file whose name matches. Throws when nothing\n * matches, rather than failing silently.\n */\n async removeFile(name: string | RegExp): Promise<void> {\n const matches = await this.getFiles({ name });\n if (matches.length === 0) {\n throw new Error(\n `FileUploadHarness.removeFile: no attached file matching ${String(name)}.`,\n );\n }\n await matches[0].remove();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}