ngwr 10.2.0 → 11.0.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 (471) hide show
  1. package/README.md +39 -19
  2. package/anchor/styles/_index.scss +4 -4
  3. package/back-top/styles/_index.scss +6 -1
  4. package/blur-text/styles/_index.scss +13 -0
  5. package/button/styles/_index.scss +11 -6
  6. package/carousel/styles/_index.scss +13 -2
  7. package/cascader/styles/_index.scss +2 -2
  8. package/circular-text/styles/_index.scss +2 -0
  9. package/collapse/styles/_index.scss +1 -1
  10. package/color-picker/styles/_index.scss +6 -1
  11. package/compare/styles/_index.scss +1 -2
  12. package/context-menu/styles/_index.scss +6 -1
  13. package/descriptions/styles/_index.scss +2 -2
  14. package/dialog/styles/_index.scss +38 -0
  15. package/drawer/styles/_index.scss +20 -1
  16. package/dropdown/styles/_index.scss +19 -5
  17. package/empty/styles/_index.scss +10 -0
  18. package/fesm2022/ngwr-action-sheet.mjs +15 -5
  19. package/fesm2022/ngwr-action-sheet.mjs.map +1 -1
  20. package/fesm2022/ngwr-affix.mjs +43 -16
  21. package/fesm2022/ngwr-affix.mjs.map +1 -1
  22. package/fesm2022/ngwr-alert.mjs +3 -3
  23. package/fesm2022/ngwr-anchor.mjs +20 -8
  24. package/fesm2022/ngwr-anchor.mjs.map +1 -1
  25. package/fesm2022/ngwr-aurora.mjs +4 -4
  26. package/fesm2022/ngwr-aurora.mjs.map +1 -1
  27. package/fesm2022/ngwr-avatar.mjs +33 -9
  28. package/fesm2022/ngwr-avatar.mjs.map +1 -1
  29. package/fesm2022/ngwr-back-top.mjs +8 -4
  30. package/fesm2022/ngwr-back-top.mjs.map +1 -1
  31. package/fesm2022/ngwr-badge.mjs +6 -6
  32. package/fesm2022/ngwr-badge.mjs.map +1 -1
  33. package/fesm2022/ngwr-bar-chart.mjs +32 -11
  34. package/fesm2022/ngwr-bar-chart.mjs.map +1 -1
  35. package/fesm2022/ngwr-blur-text.mjs +4 -4
  36. package/fesm2022/ngwr-blur-text.mjs.map +1 -1
  37. package/fesm2022/ngwr-border-glow.mjs +4 -4
  38. package/fesm2022/ngwr-border-glow.mjs.map +1 -1
  39. package/fesm2022/ngwr-breadcrumbs.mjs +9 -8
  40. package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
  41. package/fesm2022/ngwr-burger.mjs +11 -6
  42. package/fesm2022/ngwr-burger.mjs.map +1 -1
  43. package/fesm2022/ngwr-button-testing.mjs +96 -0
  44. package/fesm2022/ngwr-button-testing.mjs.map +1 -0
  45. package/fesm2022/ngwr-button.mjs +89 -24
  46. package/fesm2022/ngwr-button.mjs.map +1 -1
  47. package/fesm2022/ngwr-calendar-heatmap.mjs +42 -10
  48. package/fesm2022/ngwr-calendar-heatmap.mjs.map +1 -1
  49. package/fesm2022/ngwr-calendar.mjs +108 -9
  50. package/fesm2022/ngwr-calendar.mjs.map +1 -1
  51. package/fesm2022/ngwr-card.mjs +10 -10
  52. package/fesm2022/ngwr-card.mjs.map +1 -1
  53. package/fesm2022/ngwr-carousel-testing.mjs +377 -0
  54. package/fesm2022/ngwr-carousel-testing.mjs.map +1 -0
  55. package/fesm2022/ngwr-carousel.mjs +72 -18
  56. package/fesm2022/ngwr-carousel.mjs.map +1 -1
  57. package/fesm2022/ngwr-cascader-testing.mjs +534 -0
  58. package/fesm2022/ngwr-cascader-testing.mjs.map +1 -0
  59. package/fesm2022/ngwr-cascader.mjs +4 -4
  60. package/fesm2022/ngwr-cascader.mjs.map +1 -1
  61. package/fesm2022/ngwr-checkbox-testing.mjs +90 -0
  62. package/fesm2022/ngwr-checkbox-testing.mjs.map +1 -0
  63. package/fesm2022/ngwr-checkbox.mjs +15 -9
  64. package/fesm2022/ngwr-checkbox.mjs.map +1 -1
  65. package/fesm2022/ngwr-circular-text.mjs +4 -4
  66. package/fesm2022/ngwr-circular-text.mjs.map +1 -1
  67. package/fesm2022/ngwr-click-spark.mjs +4 -4
  68. package/fesm2022/ngwr-click-spark.mjs.map +1 -1
  69. package/fesm2022/ngwr-clipboard.mjs +18 -4
  70. package/fesm2022/ngwr-clipboard.mjs.map +1 -1
  71. package/fesm2022/ngwr-collapse-testing.mjs +368 -0
  72. package/fesm2022/ngwr-collapse-testing.mjs.map +1 -0
  73. package/fesm2022/ngwr-collapse.mjs +9 -9
  74. package/fesm2022/ngwr-color-picker.mjs +139 -19
  75. package/fesm2022/ngwr-color-picker.mjs.map +1 -1
  76. package/fesm2022/ngwr-command-palette-testing.mjs +589 -0
  77. package/fesm2022/ngwr-command-palette-testing.mjs.map +1 -0
  78. package/fesm2022/ngwr-command-palette.mjs +60 -10
  79. package/fesm2022/ngwr-command-palette.mjs.map +1 -1
  80. package/fesm2022/ngwr-compare.mjs +105 -15
  81. package/fesm2022/ngwr-compare.mjs.map +1 -1
  82. package/fesm2022/ngwr-confetti.mjs +3 -3
  83. package/fesm2022/ngwr-config.mjs +106 -0
  84. package/fesm2022/ngwr-config.mjs.map +1 -0
  85. package/fesm2022/ngwr-context-menu-testing.mjs +631 -0
  86. package/fesm2022/ngwr-context-menu-testing.mjs.map +1 -0
  87. package/fesm2022/ngwr-context-menu.mjs +104 -18
  88. package/fesm2022/ngwr-context-menu.mjs.map +1 -1
  89. package/fesm2022/ngwr-cookie.mjs +8 -4
  90. package/fesm2022/ngwr-cookie.mjs.map +1 -1
  91. package/fesm2022/ngwr-counter.mjs +17 -9
  92. package/fesm2022/ngwr-counter.mjs.map +1 -1
  93. package/fesm2022/ngwr-date-adapter-fns.mjs +3 -3
  94. package/fesm2022/ngwr-date-adapter-luxon.mjs +55 -7
  95. package/fesm2022/ngwr-date-adapter-luxon.mjs.map +1 -1
  96. package/fesm2022/ngwr-date-adapter.mjs +57 -11
  97. package/fesm2022/ngwr-date-adapter.mjs.map +1 -1
  98. package/fesm2022/ngwr-date-picker-testing.mjs +766 -0
  99. package/fesm2022/ngwr-date-picker-testing.mjs.map +1 -0
  100. package/fesm2022/ngwr-date-picker.mjs +409 -57
  101. package/fesm2022/ngwr-date-picker.mjs.map +1 -1
  102. package/fesm2022/ngwr-decrypt-text.mjs +30 -12
  103. package/fesm2022/ngwr-decrypt-text.mjs.map +1 -1
  104. package/fesm2022/ngwr-density.mjs +6 -6
  105. package/fesm2022/ngwr-descriptions.mjs +6 -6
  106. package/fesm2022/ngwr-dialog-testing.mjs +89 -0
  107. package/fesm2022/ngwr-dialog-testing.mjs.map +1 -0
  108. package/fesm2022/ngwr-dialog.mjs +33 -17
  109. package/fesm2022/ngwr-dialog.mjs.map +1 -1
  110. package/fesm2022/ngwr-directives.mjs +48 -24
  111. package/fesm2022/ngwr-directives.mjs.map +1 -1
  112. package/fesm2022/ngwr-divider.mjs +3 -3
  113. package/fesm2022/ngwr-donut-chart.mjs +24 -7
  114. package/fesm2022/ngwr-donut-chart.mjs.map +1 -1
  115. package/fesm2022/ngwr-drag-drop.mjs +7 -7
  116. package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
  117. package/fesm2022/ngwr-drawer-testing.mjs +250 -0
  118. package/fesm2022/ngwr-drawer-testing.mjs.map +1 -0
  119. package/fesm2022/ngwr-drawer.mjs +37 -19
  120. package/fesm2022/ngwr-drawer.mjs.map +1 -1
  121. package/fesm2022/ngwr-dropdown-testing.mjs +291 -0
  122. package/fesm2022/ngwr-dropdown-testing.mjs.map +1 -0
  123. package/fesm2022/ngwr-dropdown.mjs +19 -11
  124. package/fesm2022/ngwr-dropdown.mjs.map +1 -1
  125. package/fesm2022/ngwr-empty.mjs +26 -9
  126. package/fesm2022/ngwr-empty.mjs.map +1 -1
  127. package/fesm2022/ngwr-event-calendar.mjs +62 -15
  128. package/fesm2022/ngwr-event-calendar.mjs.map +1 -1
  129. package/fesm2022/ngwr-falling-text.mjs +4 -4
  130. package/fesm2022/ngwr-falling-text.mjs.map +1 -1
  131. package/fesm2022/ngwr-file-upload-testing.mjs +332 -0
  132. package/fesm2022/ngwr-file-upload-testing.mjs.map +1 -0
  133. package/fesm2022/ngwr-file-upload.mjs +3 -3
  134. package/fesm2022/ngwr-form-testing.mjs +451 -0
  135. package/fesm2022/ngwr-form-testing.mjs.map +1 -0
  136. package/fesm2022/ngwr-form.mjs +28 -12
  137. package/fesm2022/ngwr-form.mjs.map +1 -1
  138. package/fesm2022/ngwr-fuzzy-text.mjs +11 -4
  139. package/fesm2022/ngwr-fuzzy-text.mjs.map +1 -1
  140. package/fesm2022/ngwr-gauge.mjs +21 -7
  141. package/fesm2022/ngwr-gauge.mjs.map +1 -1
  142. package/fesm2022/ngwr-glitch-text.mjs +4 -4
  143. package/fesm2022/ngwr-glitch-text.mjs.map +1 -1
  144. package/fesm2022/ngwr-gradient-text.mjs +4 -4
  145. package/fesm2022/ngwr-gradient-text.mjs.map +1 -1
  146. package/fesm2022/ngwr-hotkey.mjs +31 -10
  147. package/fesm2022/ngwr-hotkey.mjs.map +1 -1
  148. package/fesm2022/ngwr-i18n-en.mjs +61 -0
  149. package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
  150. package/fesm2022/ngwr-i18n-ru.mjs +59 -0
  151. package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
  152. package/fesm2022/ngwr-i18n.mjs +9 -9
  153. package/fesm2022/ngwr-icon.mjs +6 -6
  154. package/fesm2022/ngwr-image-cropper.mjs +26 -3
  155. package/fesm2022/ngwr-image-cropper.mjs.map +1 -1
  156. package/fesm2022/ngwr-input-number-testing.mjs +306 -0
  157. package/fesm2022/ngwr-input-number-testing.mjs.map +1 -0
  158. package/fesm2022/ngwr-input-number.mjs +37 -5
  159. package/fesm2022/ngwr-input-number.mjs.map +1 -1
  160. package/fesm2022/ngwr-input-otp-testing.mjs +419 -0
  161. package/fesm2022/ngwr-input-otp-testing.mjs.map +1 -0
  162. package/fesm2022/ngwr-input-otp.mjs +39 -8
  163. package/fesm2022/ngwr-input-otp.mjs.map +1 -1
  164. package/fesm2022/ngwr-input-testing.mjs +102 -0
  165. package/fesm2022/ngwr-input-testing.mjs.map +1 -0
  166. package/fesm2022/ngwr-input.mjs +62 -25
  167. package/fesm2022/ngwr-input.mjs.map +1 -1
  168. package/fesm2022/ngwr-keyboard.mjs +3 -3
  169. package/fesm2022/ngwr-knob.mjs +46 -10
  170. package/fesm2022/ngwr-knob.mjs.map +1 -1
  171. package/fesm2022/ngwr-layout.mjs +36 -20
  172. package/fesm2022/ngwr-layout.mjs.map +1 -1
  173. package/fesm2022/ngwr-lightbox.mjs +35 -8
  174. package/fesm2022/ngwr-lightbox.mjs.map +1 -1
  175. package/fesm2022/ngwr-line-chart.mjs +19 -6
  176. package/fesm2022/ngwr-line-chart.mjs.map +1 -1
  177. package/fesm2022/ngwr-list.mjs +14 -9
  178. package/fesm2022/ngwr-list.mjs.map +1 -1
  179. package/fesm2022/ngwr-loading-bar.mjs +71 -31
  180. package/fesm2022/ngwr-loading-bar.mjs.map +1 -1
  181. package/fesm2022/ngwr-markdown-testing.mjs +516 -0
  182. package/fesm2022/ngwr-markdown-testing.mjs.map +1 -0
  183. package/fesm2022/ngwr-markdown.mjs +1492 -0
  184. package/fesm2022/ngwr-markdown.mjs.map +1 -0
  185. package/fesm2022/ngwr-marquee.mjs +19 -8
  186. package/fesm2022/ngwr-marquee.mjs.map +1 -1
  187. package/fesm2022/ngwr-media.mjs +3 -3
  188. package/fesm2022/ngwr-mention-testing.mjs +513 -0
  189. package/fesm2022/ngwr-mention-testing.mjs.map +1 -0
  190. package/fesm2022/ngwr-mention.mjs +16 -7
  191. package/fesm2022/ngwr-mention.mjs.map +1 -1
  192. package/fesm2022/ngwr-meta.mjs +28 -13
  193. package/fesm2022/ngwr-meta.mjs.map +1 -1
  194. package/fesm2022/ngwr-meter-group.mjs +22 -8
  195. package/fesm2022/ngwr-meter-group.mjs.map +1 -1
  196. package/fesm2022/ngwr-overlay.mjs +57 -8
  197. package/fesm2022/ngwr-overlay.mjs.map +1 -1
  198. package/fesm2022/ngwr-page-header.mjs +3 -3
  199. package/fesm2022/ngwr-pagination-testing.mjs +389 -0
  200. package/fesm2022/ngwr-pagination-testing.mjs.map +1 -0
  201. package/fesm2022/ngwr-pagination.mjs +27 -11
  202. package/fesm2022/ngwr-pagination.mjs.map +1 -1
  203. package/fesm2022/ngwr-pipes.mjs +21 -21
  204. package/fesm2022/ngwr-platform.mjs +9 -9
  205. package/fesm2022/ngwr-popconfirm-testing.mjs +309 -0
  206. package/fesm2022/ngwr-popconfirm-testing.mjs.map +1 -0
  207. package/fesm2022/ngwr-popconfirm.mjs +99 -21
  208. package/fesm2022/ngwr-popconfirm.mjs.map +1 -1
  209. package/fesm2022/ngwr-popover-testing.mjs +316 -0
  210. package/fesm2022/ngwr-popover-testing.mjs.map +1 -0
  211. package/fesm2022/ngwr-popover.mjs +48 -10
  212. package/fesm2022/ngwr-popover.mjs.map +1 -1
  213. package/fesm2022/ngwr-progress.mjs +3 -3
  214. package/fesm2022/ngwr-pull-to-refresh.mjs +19 -4
  215. package/fesm2022/ngwr-pull-to-refresh.mjs.map +1 -1
  216. package/fesm2022/ngwr-qr.mjs +15 -5
  217. package/fesm2022/ngwr-qr.mjs.map +1 -1
  218. package/fesm2022/ngwr-radio-testing.mjs +392 -0
  219. package/fesm2022/ngwr-radio-testing.mjs.map +1 -0
  220. package/fesm2022/ngwr-radio.mjs +16 -9
  221. package/fesm2022/ngwr-radio.mjs.map +1 -1
  222. package/fesm2022/ngwr-rating-testing.mjs +384 -0
  223. package/fesm2022/ngwr-rating-testing.mjs.map +1 -0
  224. package/fesm2022/ngwr-rating.mjs +40 -5
  225. package/fesm2022/ngwr-rating.mjs.map +1 -1
  226. package/fesm2022/ngwr-result.mjs +12 -12
  227. package/fesm2022/ngwr-rotating-text.mjs +3 -3
  228. package/fesm2022/ngwr-scroll.mjs +3 -3
  229. package/fesm2022/ngwr-segmented-testing.mjs +512 -0
  230. package/fesm2022/ngwr-segmented-testing.mjs.map +1 -0
  231. package/fesm2022/ngwr-segmented.mjs +3 -3
  232. package/fesm2022/ngwr-select-testing.mjs +268 -0
  233. package/fesm2022/ngwr-select-testing.mjs.map +1 -0
  234. package/fesm2022/ngwr-select.mjs +96 -25
  235. package/fesm2022/ngwr-select.mjs.map +1 -1
  236. package/fesm2022/ngwr-shiny-text.mjs +7 -7
  237. package/fesm2022/ngwr-shiny-text.mjs.map +1 -1
  238. package/fesm2022/ngwr-sidebar.mjs +67 -14
  239. package/fesm2022/ngwr-sidebar.mjs.map +1 -1
  240. package/fesm2022/ngwr-skeleton.mjs +3 -3
  241. package/fesm2022/ngwr-slider-testing.mjs +478 -0
  242. package/fesm2022/ngwr-slider-testing.mjs.map +1 -0
  243. package/fesm2022/ngwr-slider.mjs +59 -15
  244. package/fesm2022/ngwr-slider.mjs.map +1 -1
  245. package/fesm2022/ngwr-sparkline.mjs +28 -8
  246. package/fesm2022/ngwr-sparkline.mjs.map +1 -1
  247. package/fesm2022/ngwr-speed-dial.mjs +39 -6
  248. package/fesm2022/ngwr-speed-dial.mjs.map +1 -1
  249. package/fesm2022/ngwr-spinner.mjs +14 -5
  250. package/fesm2022/ngwr-spinner.mjs.map +1 -1
  251. package/fesm2022/ngwr-splash-cursor.mjs +4 -4
  252. package/fesm2022/ngwr-splash-cursor.mjs.map +1 -1
  253. package/fesm2022/ngwr-split-text.mjs +4 -4
  254. package/fesm2022/ngwr-split-text.mjs.map +1 -1
  255. package/fesm2022/ngwr-splitter.mjs +72 -11
  256. package/fesm2022/ngwr-splitter.mjs.map +1 -1
  257. package/fesm2022/ngwr-spotlight-card.mjs +7 -7
  258. package/fesm2022/ngwr-spotlight-card.mjs.map +1 -1
  259. package/fesm2022/ngwr-squircle.mjs +6 -6
  260. package/fesm2022/ngwr-star-border.mjs +4 -4
  261. package/fesm2022/ngwr-star-border.mjs.map +1 -1
  262. package/fesm2022/ngwr-statistic.mjs +33 -16
  263. package/fesm2022/ngwr-statistic.mjs.map +1 -1
  264. package/fesm2022/ngwr-stepper-testing.mjs +477 -0
  265. package/fesm2022/ngwr-stepper-testing.mjs.map +1 -0
  266. package/fesm2022/ngwr-stepper.mjs +6 -6
  267. package/fesm2022/ngwr-storage.mjs +27 -17
  268. package/fesm2022/ngwr-storage.mjs.map +1 -1
  269. package/fesm2022/ngwr-switch-testing.mjs +77 -0
  270. package/fesm2022/ngwr-switch-testing.mjs.map +1 -0
  271. package/fesm2022/ngwr-switch.mjs +12 -6
  272. package/fesm2022/ngwr-switch.mjs.map +1 -1
  273. package/fesm2022/ngwr-table-testing.mjs +580 -0
  274. package/fesm2022/ngwr-table-testing.mjs.map +1 -0
  275. package/fesm2022/ngwr-table.mjs +105 -44
  276. package/fesm2022/ngwr-table.mjs.map +1 -1
  277. package/fesm2022/ngwr-tabs-testing.mjs +617 -0
  278. package/fesm2022/ngwr-tabs-testing.mjs.map +1 -0
  279. package/fesm2022/ngwr-tabs.mjs +44 -12
  280. package/fesm2022/ngwr-tabs.mjs.map +1 -1
  281. package/fesm2022/ngwr-textarea-testing.mjs +238 -0
  282. package/fesm2022/ngwr-textarea-testing.mjs.map +1 -0
  283. package/fesm2022/ngwr-textarea.mjs +35 -7
  284. package/fesm2022/ngwr-textarea.mjs.map +1 -1
  285. package/fesm2022/ngwr-theme.mjs +3 -3
  286. package/fesm2022/ngwr-tilt-card.mjs +7 -7
  287. package/fesm2022/ngwr-tilt-card.mjs.map +1 -1
  288. package/fesm2022/ngwr-timeline.mjs +6 -6
  289. package/fesm2022/ngwr-toast-testing.mjs +101 -0
  290. package/fesm2022/ngwr-toast-testing.mjs.map +1 -0
  291. package/fesm2022/ngwr-toast.mjs +55 -21
  292. package/fesm2022/ngwr-toast.mjs.map +1 -1
  293. package/fesm2022/ngwr-toolbar.mjs +3 -3
  294. package/fesm2022/ngwr-tour.mjs +67 -15
  295. package/fesm2022/ngwr-tour.mjs.map +1 -1
  296. package/fesm2022/ngwr-transfer-testing.mjs +538 -0
  297. package/fesm2022/ngwr-transfer-testing.mjs.map +1 -0
  298. package/fesm2022/ngwr-transfer.mjs +47 -16
  299. package/fesm2022/ngwr-transfer.mjs.map +1 -1
  300. package/fesm2022/ngwr-tree-testing.mjs +734 -0
  301. package/fesm2022/ngwr-tree-testing.mjs.map +1 -0
  302. package/fesm2022/ngwr-tree.mjs +75 -9
  303. package/fesm2022/ngwr-tree.mjs.map +1 -1
  304. package/fesm2022/ngwr-typewriter.mjs +7 -5
  305. package/fesm2022/ngwr-typewriter.mjs.map +1 -1
  306. package/fesm2022/ngwr-typography.mjs +3 -3
  307. package/fesm2022/ngwr-version.mjs +1 -1
  308. package/fesm2022/ngwr-version.mjs.map +1 -1
  309. package/fesm2022/ngwr-virtual-scroll.mjs +33 -7
  310. package/fesm2022/ngwr-virtual-scroll.mjs.map +1 -1
  311. package/fesm2022/ngwr-waves.mjs +5 -5
  312. package/fesm2022/ngwr-waves.mjs.map +1 -1
  313. package/fesm2022/ngwr-window.mjs +88 -18
  314. package/fesm2022/ngwr-window.mjs.map +1 -1
  315. package/gauge/styles/_index.scss +1 -1
  316. package/glitch-text/styles/_index.scss +4 -0
  317. package/i18n/en.json +56 -0
  318. package/i18n/ru.json +56 -0
  319. package/image-cropper/styles/_index.scss +13 -1
  320. package/input/styles/_index.scss +2 -2
  321. package/input-number/styles/_index.scss +7 -2
  322. package/knob/styles/_index.scss +8 -1
  323. package/layout/styles/_index.scss +3 -3
  324. package/lightbox/styles/_index.scss +10 -2
  325. package/line-chart/styles/_index.scss +6 -0
  326. package/llms-full.txt +151 -4
  327. package/llms.txt +57 -8
  328. package/loading-bar/styles/_index.scss +1 -2
  329. package/markdown/styles/_index.scss +296 -0
  330. package/marquee/styles/_index.scss +12 -0
  331. package/mcp/api.js +512 -0
  332. package/mcp/catalog.js +157 -0
  333. package/mcp/server.js +273 -0
  334. package/mcp/tools.js +366 -0
  335. package/meter-group/styles/_index.scss +1 -1
  336. package/package.json +186 -35
  337. package/pagination/styles/_index.scss +6 -6
  338. package/popover/styles/_index.scss +37 -5
  339. package/rating/styles/_index.scss +10 -0
  340. package/schematics/use/symbol-map.json +2 -0
  341. package/segmented/styles/_index.scss +7 -0
  342. package/select/styles/_index.scss +29 -9
  343. package/sidebar/styles/_index.scss +30 -5
  344. package/slider/styles/_index.scss +15 -0
  345. package/speed-dial/styles/_index.scss +20 -0
  346. package/split-text/styles/_index.scss +13 -0
  347. package/star-border/styles/_index.scss +2 -0
  348. package/stepper/styles/_index.scss +1 -1
  349. package/styles/_grid.scss +4 -4
  350. package/styles.scss +1 -0
  351. package/switch/styles/_index.scss +5 -3
  352. package/table/styles/_index.scss +22 -11
  353. package/tabs/styles/_index.scss +11 -1
  354. package/textarea/styles/_index.scss +5 -0
  355. package/theme/styles/_colors.scss +29 -13
  356. package/theme/styles/_dark.scss +11 -3
  357. package/theme/styles/_mixins.scss +3 -0
  358. package/timeline/styles/_index.scss +2 -2
  359. package/toast/styles/_index.scss +17 -8
  360. package/toolbar/styles/_index.scss +3 -3
  361. package/tour/styles/_index.scss +7 -1
  362. package/tree/styles/_index.scss +5 -3
  363. package/types/ngwr-action-sheet.d.ts +9 -1
  364. package/types/ngwr-affix.d.ts +7 -1
  365. package/types/ngwr-anchor.d.ts +8 -1
  366. package/types/ngwr-avatar.d.ts +13 -3
  367. package/types/ngwr-bar-chart.d.ts +16 -0
  368. package/types/ngwr-burger.d.ts +6 -2
  369. package/types/ngwr-button-testing.d.ts +85 -0
  370. package/types/ngwr-button.d.ts +58 -10
  371. package/types/ngwr-calendar-heatmap.d.ts +16 -2
  372. package/types/ngwr-calendar.d.ts +37 -1
  373. package/types/ngwr-carousel-testing.d.ts +257 -0
  374. package/types/ngwr-carousel.d.ts +20 -4
  375. package/types/ngwr-cascader-testing.d.ts +392 -0
  376. package/types/ngwr-checkbox-testing.d.ts +77 -0
  377. package/types/ngwr-checkbox.d.ts +7 -2
  378. package/types/ngwr-clipboard.d.ts +8 -1
  379. package/types/ngwr-collapse-testing.d.ts +290 -0
  380. package/types/ngwr-color-picker.d.ts +20 -11
  381. package/types/ngwr-command-palette-testing.d.ts +437 -0
  382. package/types/ngwr-command-palette.d.ts +25 -2
  383. package/types/ngwr-compare.d.ts +50 -2
  384. package/types/ngwr-config.d.ts +176 -0
  385. package/types/ngwr-context-menu-testing.d.ts +401 -0
  386. package/types/ngwr-context-menu.d.ts +65 -17
  387. package/types/ngwr-counter.d.ts +6 -1
  388. package/types/ngwr-date-adapter-luxon.d.ts +26 -0
  389. package/types/ngwr-date-picker-testing.d.ts +518 -0
  390. package/types/ngwr-date-picker.d.ts +128 -8
  391. package/types/ngwr-dialog-testing.d.ts +79 -0
  392. package/types/ngwr-dialog.d.ts +13 -0
  393. package/types/ngwr-directives.d.ts +10 -1
  394. package/types/ngwr-donut-chart.d.ts +8 -1
  395. package/types/ngwr-drawer-testing.d.ts +196 -0
  396. package/types/ngwr-drawer.d.ts +15 -0
  397. package/types/ngwr-dropdown-testing.d.ts +202 -0
  398. package/types/ngwr-dropdown.d.ts +7 -1
  399. package/types/ngwr-empty.d.ts +19 -4
  400. package/types/ngwr-event-calendar.d.ts +26 -1
  401. package/types/ngwr-file-upload-testing.d.ts +194 -0
  402. package/types/ngwr-form-testing.d.ts +379 -0
  403. package/types/ngwr-form.d.ts +17 -0
  404. package/types/ngwr-gauge.d.ts +13 -1
  405. package/types/ngwr-hotkey.d.ts +2 -0
  406. package/types/ngwr-image-cropper.d.ts +10 -0
  407. package/types/ngwr-input-number-testing.d.ts +226 -0
  408. package/types/ngwr-input-number.d.ts +29 -1
  409. package/types/ngwr-input-otp-testing.d.ts +299 -0
  410. package/types/ngwr-input-otp.d.ts +23 -2
  411. package/types/ngwr-input-testing.d.ts +84 -0
  412. package/types/ngwr-input.d.ts +20 -6
  413. package/types/ngwr-knob.d.ts +18 -0
  414. package/types/ngwr-layout.d.ts +1 -0
  415. package/types/ngwr-lightbox.d.ts +17 -3
  416. package/types/ngwr-line-chart.d.ts +9 -2
  417. package/types/ngwr-list.d.ts +7 -2
  418. package/types/ngwr-loading-bar.d.ts +4 -7
  419. package/types/ngwr-markdown-testing.d.ts +462 -0
  420. package/types/ngwr-markdown.d.ts +534 -0
  421. package/types/ngwr-marquee.d.ts +12 -2
  422. package/types/ngwr-mention-testing.d.ts +359 -0
  423. package/types/ngwr-meta.d.ts +4 -2
  424. package/types/ngwr-meter-group.d.ts +11 -1
  425. package/types/ngwr-overlay.d.ts +33 -2
  426. package/types/ngwr-pagination-testing.d.ts +291 -0
  427. package/types/ngwr-pagination.d.ts +7 -1
  428. package/types/ngwr-popconfirm-testing.d.ts +235 -0
  429. package/types/ngwr-popconfirm.d.ts +31 -21
  430. package/types/ngwr-popover-testing.d.ts +221 -0
  431. package/types/ngwr-popover.d.ts +19 -2
  432. package/types/ngwr-pull-to-refresh.d.ts +7 -0
  433. package/types/ngwr-qr.d.ts +9 -1
  434. package/types/ngwr-radio-testing.d.ts +296 -0
  435. package/types/ngwr-radio.d.ts +8 -2
  436. package/types/ngwr-rating-testing.d.ts +291 -0
  437. package/types/ngwr-rating.d.ts +23 -0
  438. package/types/ngwr-segmented-testing.d.ts +401 -0
  439. package/types/ngwr-select-testing.d.ts +175 -0
  440. package/types/ngwr-select.d.ts +45 -4
  441. package/types/ngwr-sidebar.d.ts +17 -2
  442. package/types/ngwr-slider-testing.d.ts +329 -0
  443. package/types/ngwr-slider.d.ts +35 -1
  444. package/types/ngwr-sparkline.d.ts +12 -2
  445. package/types/ngwr-speed-dial.d.ts +17 -18
  446. package/types/ngwr-spinner.d.ts +8 -1
  447. package/types/ngwr-splitter.d.ts +24 -1
  448. package/types/ngwr-statistic.d.ts +12 -2
  449. package/types/ngwr-stepper-testing.d.ts +346 -0
  450. package/types/ngwr-storage.d.ts +10 -1
  451. package/types/ngwr-switch-testing.d.ts +66 -0
  452. package/types/ngwr-switch.d.ts +7 -2
  453. package/types/ngwr-table-testing.d.ts +423 -0
  454. package/types/ngwr-table.d.ts +42 -0
  455. package/types/ngwr-tabs-testing.d.ts +470 -0
  456. package/types/ngwr-tabs.d.ts +9 -0
  457. package/types/ngwr-textarea-testing.d.ts +184 -0
  458. package/types/ngwr-textarea.d.ts +7 -2
  459. package/types/ngwr-toast-testing.d.ts +80 -0
  460. package/types/ngwr-toast.d.ts +19 -4
  461. package/types/ngwr-tour.d.ts +27 -0
  462. package/types/ngwr-transfer-testing.d.ts +444 -0
  463. package/types/ngwr-transfer.d.ts +16 -1
  464. package/types/ngwr-tree-testing.d.ts +501 -0
  465. package/types/ngwr-tree.d.ts +33 -0
  466. package/types/ngwr-version.d.ts +1 -1
  467. package/types/ngwr-virtual-scroll.d.ts +13 -1
  468. package/types/ngwr-window.d.ts +23 -2
  469. package/typewriter/styles/_index.scss +1 -1
  470. package/typography/styles/_index.scss +1 -1
  471. package/window/styles/_index.scss +32 -9
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-dialog.mjs","sources":["../../../projects/lib/dialog/dialog-ref.ts","../../../projects/lib/dialog/tokens/dialog-data.token.ts","../../../projects/lib/dialog/tokens/dialog-ref.token.ts","../../../projects/lib/dialog/dialog.ts","../../../projects/lib/dialog/directives/dialog-title.ts","../../../projects/lib/dialog/directives/dialog-content.ts","../../../projects/lib/dialog/directives/dialog-footer.ts","../../../projects/lib/dialog/directives/dialog-close.ts","../../../projects/lib/dialog/ngwr-dialog.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport type { ConfigurableFocusTrap } from '@angular/cdk/a11y';\nimport type { OverlayRef } from '@angular/cdk/overlay';\nimport type { ComponentRef } from '@angular/core';\n\nimport { ReplaySubject } from 'rxjs';\n\n/**\n * Handle returned by `WrDialog.open()`.\n *\n * Wraps the underlying `OverlayRef` and tracks the close result. It is also\n * provided inside the dialog's own injector, so the projected content can\n * inject it and close itself — the counterpart to `[wrDialogClose]` when the\n * close is programmatic (after a save succeeds, say) rather than a click.\n *\n * @example\n * ```ts\n * // Caller side.\n * const ref = dialog.open<ConfirmComponent, boolean>(ConfirmComponent);\n * const result = await ref.awaitClose(); // boolean | undefined\n * ```\n *\n * @example\n * ```ts\n * // Content side — the dialog closes itself.\n * @Component({...})\n * export class ConfirmComponent {\n * private readonly ref = inject(WrDialogRef);\n *\n * save(): void {\n * this.store.save();\n * this.ref.close(true);\n * }\n * }\n * ```\n */\nexport class WrDialogRef<C, R = unknown> {\n /**\n * Emits the close result once and completes.\n *\n * A `ReplaySubject`, not a plain `Subject`, so the result survives a late\n * subscriber: content can close itself before `open()` has even returned, and\n * `awaitClose()` may be called long after the dismissal — both would otherwise\n * see only `complete` and resolve `undefined`.\n */\n readonly closed = new ReplaySubject<R | undefined>(1);\n\n /** @internal */\n componentRef: ComponentRef<C> | null = null;\n\n /** @internal */\n focusTrap: ConfigurableFocusTrap | null = null;\n\n /** @internal */\n previouslyFocused: HTMLElement | null = null;\n\n constructor(private readonly _overlayRef: OverlayRef) {}\n\n /** The instantiated dialog component. */\n get componentInstance(): C {\n if (!this.componentRef) {\n throw new Error('WrDialogRef: component not yet attached');\n }\n return this.componentRef.instance;\n }\n\n private isClosed = false;\n\n /** Close the dialog, optionally returning a result. */\n close(result?: R): void {\n if (this.isClosed) return;\n this.isClosed = true;\n this.closed.next(result);\n this.closed.complete();\n // Content that closes itself while constructing gets here with\n // `OverlayRef.attach()` still on the stack — `componentRef` is assigned\n // only once attach returns. Disposing mid-attach leaves the CDK writing to\n // a detached host, so let the current task finish first.\n if (!this.componentRef) {\n queueMicrotask(() => this.teardown());\n return;\n }\n this.teardown();\n }\n\n private teardown(): void {\n this.focusTrap?.destroy();\n this.focusTrap = null;\n const restore = this.previouslyFocused;\n this.previouslyFocused = null;\n this._overlayRef.dispose();\n // Drop the destroyed component so a retained ref doesn't pin its instance,\n // host element and view in memory.\n this.componentRef = null;\n // Restore focus after disposal so the trigger is reachable again.\n if (restore && typeof restore.focus === 'function') {\n restore.focus();\n }\n }\n\n /** Resolves with the close result when the dialog is dismissed. */\n awaitClose(): Promise<R | undefined> {\n return new Promise(resolve => {\n this.closed.subscribe({\n next: value => resolve(value),\n complete: () => resolve(undefined),\n });\n });\n }\n\n /** Underlying overlay ref — escape hatch for advanced cases. */\n get overlayRef(): OverlayRef {\n return this._overlayRef;\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { InjectionToken } from '@angular/core';\n\n/**\n * Token that exposes the `data` payload passed to `WrDialog.open()`.\n *\n * @example\n * ```ts\n * @Component({...})\n * export class ConfirmComponent {\n * readonly data = inject<ConfirmData>(WR_DIALOG_DATA);\n * }\n * ```\n */\nexport const WR_DIALOG_DATA = new InjectionToken<unknown>('WR_DIALOG_DATA');\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { InjectionToken } from '@angular/core';\n\nimport type { WrDialogRef } from '../dialog-ref';\n\n/**\n * Token exposing the open dialog's `WrDialogRef` to components and\n * directives rendered inside it (e.g. `[wrDialogClose]`).\n *\n * **Prefer `inject(WrDialogRef)`** — the ref is provided under the class token\n * too, and the class path is the documented one. It already covers both cases\n * you might reach for a token for: `inject(WrDialogRef, { optional: true })`\n * works for content that also renders outside a dialog, and\n * `inject<WrDialogRef<ConfirmComponent, boolean>>(WrDialogRef)` types the\n * generics without a cast.\n *\n * This token is the same object under a second key. It exists for the library's\n * own directives (`[wrDialogClose]`) and for swapping the provider out — a test\n * stub, say — without touching the class.\n *\n * @example\n * ```ts\n * @Component({...})\n * export class ConfirmComponent {\n * private readonly ref = inject<WrDialogRef<ConfirmComponent, boolean>>(WrDialogRef);\n *\n * confirm(): void {\n * this.ref.close(true);\n * }\n * }\n * ```\n */\nexport const WR_DIALOG_REF = new InjectionToken<WrDialogRef<unknown, unknown>>('WR_DIALOG_REF');\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ConfigurableFocusTrapFactory } from '@angular/cdk/a11y';\nimport { type OverlayRef, ScrollStrategyOptions } from '@angular/cdk/overlay';\nimport { ComponentPortal, type ComponentType } from '@angular/cdk/portal';\nimport { isPlatformBrowser } from '@angular/common';\nimport { EnvironmentInjector, Service, Injector, PLATFORM_ID, afterNextRender, inject } from '@angular/core';\n\nimport { WrI18n } from 'ngwr/i18n';\nimport { WR_OVERLAY, WR_RESPONSIVE_OVERLAYS, wrAppendOverlayClose, wrPresentAsSheet } from 'ngwr/overlay';\n\nimport { WrDialogRef } from './dialog-ref';\nimport type { WrDialogOptions } from './interfaces';\nimport { WR_DIALOG_DATA, WR_DIALOG_REF } from './tokens';\n\nconst DEFAULT_PANEL_CLASS = 'wr-dialog-panel';\nconst DEFAULT_BACKDROP_CLASS = 'wr-dialog-backdrop';\n\n/**\n * Opens dialog components in an isolated NGWR overlay.\n *\n * Uses `WR_OVERLAY` so it composes cleanly with `provideWrOverlay()`\n * — dialogs render into NGWR's own overlay container and never collide\n * with other CDK consumers (Material, NG-ZORRO, etc.).\n *\n * @example\n * ```ts\n * const dialog = inject(WrDialog);\n *\n * const ref = dialog.open(ConfirmComponent, {\n * data: { message: 'Delete this item?' },\n * width: '24rem',\n * });\n *\n * const ok = await ref.awaitClose();\n * if (ok) remove();\n * ```\n *\n * @see https://ngwr.dev/reference/components/dialog\n */\n@Service()\nexport class WrDialog {\n private readonly overlay = inject(WR_OVERLAY);\n private readonly scrollStrategies = inject(ScrollStrategyOptions);\n private readonly parentInjector = inject(EnvironmentInjector);\n private readonly focusTrapFactory = inject(ConfigurableFocusTrapFactory);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n private readonly responsiveConfig = inject(WR_RESPONSIVE_OVERLAYS);\n private readonly i18n = inject(WrI18n);\n\n open<C, R = unknown, D = unknown>(component: ComponentType<C>, options: WrDialogOptions<D> = {}): WrDialogRef<C, R> {\n const panelClasses: string[] = [DEFAULT_PANEL_CLASS];\n const extra = options.panelClass;\n if (typeof extra === 'string') {\n panelClasses.push(extra);\n } else if (extra) {\n for (const cls of extra) panelClasses.push(cls);\n }\n\n // On small viewports (when opted in) present as a slide-up sheet pinned\n // to the bottom edge, full-width, instead of a centred modal.\n const asSheet = wrPresentAsSheet(options.responsive, this.responsiveConfig);\n if (asSheet) panelClasses.push('wr-overlay-sheet');\n\n const position = this.overlay.position().global().centerHorizontally();\n const overlayRef: OverlayRef = this.overlay.create({\n positionStrategy: asSheet ? position.bottom('0') : position.centerVertically(),\n scrollStrategy: this.scrollStrategies.block(),\n hasBackdrop: true,\n backdropClass: DEFAULT_BACKDROP_CLASS,\n panelClass: panelClasses,\n width: asSheet ? '100%' : options.width,\n maxWidth: asSheet ? '100%' : options.maxWidth,\n });\n\n const dialogRef = new WrDialogRef<C, R>(overlayRef);\n\n if (this.isBrowser) {\n const active = document.activeElement;\n dialogRef.previouslyFocused = active instanceof HTMLElement ? active : null;\n }\n\n const injector = Injector.create({\n parent: this.parentInjector,\n providers: [\n { provide: WR_DIALOG_DATA, useValue: options.data },\n { provide: WR_DIALOG_REF, useValue: dialogRef },\n // Provided as its own token as well, so dialog content can reach for\n // the familiar `inject(WrDialogRef)` and close itself.\n { provide: WrDialogRef, useValue: dialogRef },\n ],\n });\n\n const portal = new ComponentPortal(component, null, injector);\n dialogRef.componentRef = overlayRef.attach(portal);\n\n if (this.isBrowser) {\n const host = overlayRef.overlayElement;\n host.setAttribute('role', 'dialog');\n host.setAttribute('aria-modal', 'true');\n // Built-in dismiss. Appended after the content portal so it paints above\n // it, and marked on the panel so the title reserves the corner gutter.\n if (options.closable !== false) {\n host.classList.add('wr-dialog-panel--closable');\n const label = options.closeLabel ?? this.i18n.t('dialog.close');\n wrAppendOverlayClose(host, 'wr-dialog__close', label, () => dialogRef.close());\n }\n // Wire aria-labelledby to wrDialogTitle's auto-id once content is in DOM.\n // Has to wait for a render, not a microtask: attaching the portal only\n // schedules change detection, so under zoneless CD a microtask runs while\n // the content is still an empty view and the title id doesn't exist yet.\n afterNextRender(\n () => {\n const titleEl = host.querySelector<HTMLElement>('[wrDialogTitle], [wr-dialog-title]');\n if (titleEl?.id) host.setAttribute('aria-labelledby', titleEl.id);\n },\n { injector: this.parentInjector }\n );\n // Trap focus inside the dialog and move initial focus in.\n const trap = this.focusTrapFactory.create(host);\n dialogRef.focusTrap = trap;\n void trap.focusInitialElementWhenReady();\n }\n\n // Overlay subscriptions complete when the overlay is disposed, so no\n // explicit teardown is required.\n if (options.closeOnBackdropClick !== false) {\n overlayRef.backdropClick().subscribe(() => dialogRef.close());\n }\n if (options.closeOnEscape !== false) {\n overlayRef.keydownEvents().subscribe(event => {\n if (event.key === 'Escape') {\n event.preventDefault();\n dialogRef.close();\n }\n });\n }\n\n return dialogRef;\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive, ElementRef, inject } from '@angular/core';\n\nlet uid = 0;\n\n/**\n * Styles a dialog title row. Use on a heading inside an opened dialog.\n * Auto-assigns an `id` so the dialog panel can reference it via\n * `aria-labelledby`.\n *\n * @example\n * ```html\n * <h2 wrDialogTitle>Confirm delete</h2>\n * ```\n */\n@Directive({\n selector: '[wrDialogTitle]',\n host: { class: 'wr-dialog__title', '[attr.id]': 'id' },\n})\nexport class WrDialogTitle {\n /** Generated id used for `aria-labelledby` wiring. */\n readonly id = `wr-dialog-title-${++uid}`;\n\n /** @internal */\n readonly elementRef = inject(ElementRef<HTMLElement>);\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive } from '@angular/core';\n\n/**\n * Styles the scrollable body section of a dialog.\n *\n * @example\n * ```html\n * <div wrDialogContent>…body…</div>\n * ```\n */\n@Directive({\n selector: '[wrDialogContent]',\n host: { class: 'wr-dialog__content' },\n})\nexport class WrDialogContent {}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive, computed, input } from '@angular/core';\n\n/**\n * Footer row, typically holding action buttons.\n *\n * @example\n * ```html\n * <div wrDialogFooter align=\"end\">\n * <wr-btn wrDialogClose>Cancel</wr-btn>\n * <wr-btn color=\"danger\" (click)=\"confirm()\">Delete</wr-btn>\n * </div>\n * ```\n */\n@Directive({\n selector: '[wrDialogFooter]',\n host: { '[class]': 'classes()' },\n})\nexport class WrDialogFooter {\n /**\n * Horizontal alignment of the children.\n *\n * @default 'end'\n */\n readonly align = input<'start' | 'center' | 'end'>('end');\n\n protected readonly classes = computed(() => `wr-dialog__footer wr-dialog__footer--${this.align()}`);\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive, inject, input } from '@angular/core';\n\nimport type { WrDialogRef } from '../dialog-ref';\nimport { WR_DIALOG_REF } from '../tokens';\n\n/**\n * Closes the dialog when the host element is clicked.\n *\n * Optionally passes a `[wrDialogClose]` value as the close result.\n *\n * @example\n * ```html\n * <wr-btn wrDialogClose>Cancel</wr-btn>\n * <wr-btn color=\"primary\" [wrDialogClose]=\"true\">Confirm</wr-btn>\n * ```\n */\n@Directive({\n selector: '[wrDialogClose]',\n host: { '(click)': 'onClick()' },\n})\nexport class WrDialogClose<R = unknown> {\n /**\n * Value to pass to `close()`. When unset — or used as a bare attribute — the\n * dialog closes with `undefined`.\n */\n readonly result = input<R | undefined, R | undefined | ''>(undefined, {\n alias: 'wrDialogClose',\n // A bare `wrDialogClose` attribute arrives as the empty string; that means\n // \"no result\", not a result of `''`. Matches `wrDrawerClose`.\n transform: value => (value === '' ? undefined : value),\n });\n\n private readonly ref = inject<WrDialogRef<unknown, R>>(WR_DIALOG_REF, { optional: true });\n\n protected onClick(): void {\n this.ref?.close(this.result());\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngwr-dialog.mjs","sources":["../../../projects/lib/dialog/dialog-ref.ts","../../../projects/lib/dialog/tokens/dialog-data.token.ts","../../../projects/lib/dialog/tokens/dialog-ref.token.ts","../../../projects/lib/dialog/dialog.ts","../../../projects/lib/dialog/directives/dialog-title.ts","../../../projects/lib/dialog/directives/dialog-content.ts","../../../projects/lib/dialog/directives/dialog-footer.ts","../../../projects/lib/dialog/directives/dialog-close.ts","../../../projects/lib/dialog/ngwr-dialog.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport type { ConfigurableFocusTrap } from '@angular/cdk/a11y';\nimport type { OverlayRef } from '@angular/cdk/overlay';\nimport type { ComponentRef } from '@angular/core';\n\nimport { ReplaySubject } from 'rxjs';\n\n/**\n * Handle returned by `WrDialog.open()`.\n *\n * Wraps the underlying `OverlayRef` and tracks the close result. It is also\n * provided inside the dialog's own injector, so the projected content can\n * inject it and close itself — the counterpart to `[wrDialogClose]` when the\n * close is programmatic (after a save succeeds, say) rather than a click.\n *\n * @example\n * ```ts\n * // Caller side.\n * const ref = dialog.open<ConfirmComponent, boolean>(ConfirmComponent);\n * const result = await ref.awaitClose(); // boolean | undefined\n * ```\n *\n * @example\n * ```ts\n * // Content side — the dialog closes itself.\n * @Component({...})\n * export class ConfirmComponent {\n * private readonly ref = inject(WrDialogRef);\n *\n * save(): void {\n * this.store.save();\n * this.ref.close(true);\n * }\n * }\n * ```\n */\nexport class WrDialogRef<C, R = unknown> {\n /**\n * Emits the close result once and completes.\n *\n * A `ReplaySubject`, not a plain `Subject`, so the result survives a late\n * subscriber: content can close itself before `open()` has even returned, and\n * `awaitClose()` may be called long after the dismissal — both would otherwise\n * see only `complete` and resolve `undefined`.\n */\n readonly closed = new ReplaySubject<R | undefined>(1);\n\n /** @internal */\n componentRef: ComponentRef<C> | null = null;\n\n /** @internal */\n focusTrap: ConfigurableFocusTrap | null = null;\n\n /** @internal */\n previouslyFocused: HTMLElement | null = null;\n\n constructor(private readonly _overlayRef: OverlayRef) {}\n\n /** The instantiated dialog component. */\n get componentInstance(): C {\n if (!this.componentRef) {\n throw new Error('WrDialogRef: component not yet attached');\n }\n return this.componentRef.instance;\n }\n\n private isClosed = false;\n\n /** Close the dialog, optionally returning a result. */\n close(result?: R): void {\n if (this.isClosed) return;\n this.isClosed = true;\n this.closed.next(result);\n this.closed.complete();\n // Content that closes itself while constructing gets here with\n // `OverlayRef.attach()` still on the stack — `componentRef` is assigned\n // only once attach returns. Disposing mid-attach leaves the CDK writing to\n // a detached host, so let the current task finish first.\n if (!this.componentRef) {\n queueMicrotask(() => this.teardown());\n return;\n }\n this.teardown();\n }\n\n private teardown(): void {\n this.focusTrap?.destroy();\n this.focusTrap = null;\n const restore = this.previouslyFocused;\n this.previouslyFocused = null;\n this._overlayRef.dispose();\n // Drop the destroyed component so a retained ref doesn't pin its instance,\n // host element and view in memory.\n this.componentRef = null;\n // Restore focus after disposal so the trigger is reachable again.\n if (restore && typeof restore.focus === 'function') {\n restore.focus();\n }\n }\n\n /** Resolves with the close result when the dialog is dismissed. */\n awaitClose(): Promise<R | undefined> {\n return new Promise(resolve => {\n this.closed.subscribe({\n next: value => resolve(value),\n complete: () => resolve(undefined),\n });\n });\n }\n\n /** Underlying overlay ref — escape hatch for advanced cases. */\n get overlayRef(): OverlayRef {\n return this._overlayRef;\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { InjectionToken } from '@angular/core';\n\n/**\n * Token that exposes the `data` payload passed to `WrDialog.open()`.\n *\n * @example\n * ```ts\n * @Component({...})\n * export class ConfirmComponent {\n * readonly data = inject<ConfirmData>(WR_DIALOG_DATA);\n * }\n * ```\n */\nexport const WR_DIALOG_DATA = new InjectionToken<unknown>('WR_DIALOG_DATA');\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { InjectionToken } from '@angular/core';\n\nimport type { WrDialogRef } from '../dialog-ref';\n\n/**\n * Token exposing the open dialog's `WrDialogRef` to components and\n * directives rendered inside it (e.g. `[wrDialogClose]`).\n *\n * **Prefer `inject(WrDialogRef)`** — the ref is provided under the class token\n * too, and the class path is the documented one. It already covers both cases\n * you might reach for a token for: `inject(WrDialogRef, { optional: true })`\n * works for content that also renders outside a dialog, and\n * `inject<WrDialogRef<ConfirmComponent, boolean>>(WrDialogRef)` types the\n * generics without a cast.\n *\n * This token is the same object under a second key. It exists for the library's\n * own directives (`[wrDialogClose]`) and for swapping the provider out — a test\n * stub, say — without touching the class.\n *\n * @example\n * ```ts\n * @Component({...})\n * export class ConfirmComponent {\n * private readonly ref = inject<WrDialogRef<ConfirmComponent, boolean>>(WrDialogRef);\n *\n * confirm(): void {\n * this.ref.close(true);\n * }\n * }\n * ```\n */\nexport const WR_DIALOG_REF = new InjectionToken<WrDialogRef<unknown, unknown>>('WR_DIALOG_REF');\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ConfigurableFocusTrapFactory } from '@angular/cdk/a11y';\nimport { type OverlayRef, ScrollStrategyOptions } from '@angular/cdk/overlay';\nimport { ComponentPortal, type ComponentType } from '@angular/cdk/portal';\nimport { isPlatformBrowser } from '@angular/common';\nimport { EnvironmentInjector, Service, Injector, PLATFORM_ID, afterNextRender, inject } from '@angular/core';\n\nimport { WrI18n } from 'ngwr/i18n';\nimport { WR_OVERLAY, WR_RESPONSIVE_OVERLAYS, wrAppendOverlayClose, wrPresentAsSheet } from 'ngwr/overlay';\n\nimport { WrDialogRef } from './dialog-ref';\nimport type { WrDialogOptions } from './interfaces';\nimport { WR_DIALOG_DATA, WR_DIALOG_REF } from './tokens';\n\nconst DEFAULT_PANEL_CLASS = 'wr-dialog-panel';\nconst DEFAULT_BACKDROP_CLASS = 'wr-dialog-backdrop';\n\n/**\n * Opens dialog components in an isolated NGWR overlay.\n *\n * Uses `WR_OVERLAY` so it composes cleanly with `provideWrOverlay()`\n * — dialogs render into NGWR's own overlay container and never collide\n * with other CDK consumers (Material, NG-ZORRO, etc.).\n *\n * @example\n * ```ts\n * const dialog = inject(WrDialog);\n *\n * const ref = dialog.open(ConfirmComponent, {\n * data: { message: 'Delete this item?' },\n * width: '24rem',\n * });\n *\n * const ok = await ref.awaitClose();\n * if (ok) remove();\n * ```\n *\n * @see https://ngwr.dev/reference/components/dialog\n */\n@Service()\nexport class WrDialog {\n private readonly overlay = inject(WR_OVERLAY);\n private readonly scrollStrategies = inject(ScrollStrategyOptions);\n private readonly parentInjector = inject(EnvironmentInjector);\n private readonly focusTrapFactory = inject(ConfigurableFocusTrapFactory);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n private readonly responsiveConfig = inject(WR_RESPONSIVE_OVERLAYS);\n private readonly i18n = inject(WrI18n, { optional: true });\n\n open<C, R = unknown, D = unknown>(component: ComponentType<C>, options: WrDialogOptions<D> = {}): WrDialogRef<C, R> {\n const panelClasses: string[] = [DEFAULT_PANEL_CLASS];\n const extra = options.panelClass;\n if (typeof extra === 'string') {\n panelClasses.push(extra);\n } else if (extra) {\n for (const cls of extra) panelClasses.push(cls);\n }\n\n // On small viewports (when opted in) present as a slide-up sheet pinned\n // to the bottom edge, full-width, instead of a centred modal.\n const asSheet = wrPresentAsSheet(options.responsive, this.responsiveConfig);\n if (asSheet) panelClasses.push('wr-overlay-sheet');\n\n const position = this.overlay.position().global().centerHorizontally();\n const overlayRef: OverlayRef = this.overlay.create({\n positionStrategy: asSheet ? position.bottom('0') : position.centerVertically(),\n scrollStrategy: this.scrollStrategies.block(),\n hasBackdrop: true,\n backdropClass: DEFAULT_BACKDROP_CLASS,\n panelClass: panelClasses,\n width: asSheet ? '100%' : options.width,\n maxWidth: asSheet ? '100%' : options.maxWidth,\n });\n\n const dialogRef = new WrDialogRef<C, R>(overlayRef);\n\n if (this.isBrowser) {\n const active = document.activeElement;\n dialogRef.previouslyFocused = active instanceof HTMLElement ? active : null;\n }\n\n const injector = Injector.create({\n parent: this.parentInjector,\n providers: [\n { provide: WR_DIALOG_DATA, useValue: options.data },\n { provide: WR_DIALOG_REF, useValue: dialogRef },\n // Provided as its own token as well, so dialog content can reach for\n // the familiar `inject(WrDialogRef)` and close itself.\n { provide: WrDialogRef, useValue: dialogRef },\n ],\n });\n\n const portal = new ComponentPortal(component, null, injector);\n dialogRef.componentRef = overlayRef.attach(portal);\n\n if (this.isBrowser) {\n const host = overlayRef.overlayElement;\n host.setAttribute('role', 'dialog');\n host.setAttribute('aria-modal', 'true');\n // Built-in dismiss. Appended after the content portal so it paints above\n // it, and marked on the panel so the title reserves the corner gutter.\n if (options.closable !== false) {\n host.classList.add('wr-dialog-panel--closable');\n const label = options.closeLabel ?? this.closeLabel();\n wrAppendOverlayClose(host, 'wr-dialog__close', label, () => dialogRef.close());\n }\n // Wire aria-labelledby to wrDialogTitle's auto-id once content is in DOM.\n // Has to wait for a render, not a microtask: attaching the portal only\n // schedules change detection, so under zoneless CD a microtask runs while\n // the content is still an empty view and the title id doesn't exist yet.\n afterNextRender(\n () => {\n const titleEl = host.querySelector<HTMLElement>('[wrDialogTitle], [wr-dialog-title]');\n if (titleEl?.id) host.setAttribute('aria-labelledby', titleEl.id);\n },\n { injector: this.parentInjector }\n );\n // Trap focus inside the dialog and move initial focus in.\n const trap = this.focusTrapFactory.create(host);\n dialogRef.focusTrap = trap;\n void trap.focusInitialElementWhenReady();\n }\n\n // Overlay subscriptions complete when the overlay is disposed, so no\n // explicit teardown is required.\n if (options.closeOnBackdropClick !== false) {\n overlayRef.backdropClick().subscribe(() => dialogRef.close());\n }\n if (options.closeOnEscape !== false) {\n overlayRef.keydownEvents().subscribe(event => {\n if (event.key === 'Escape') {\n event.preventDefault();\n dialogRef.close();\n }\n });\n }\n\n return dialogRef;\n }\n\n /**\n * The dismiss button's accessible name.\n *\n * Two failure modes, and resolving PER OPEN is what covers both. `t()` hands\n * back the KEY on a miss, and `WrI18n` is root-provided with an empty catalog\n * by default, so an app that never configured i18n named its dismiss button\n * \"dialog.close\" — a name axe cannot fault, because a name is present, and a\n * screen reader reads out verbatim. Resolving once at injection time fixed\n * that but froze the answer: this is a root service, constructed before an\n * async catalog has loaded, so a localized app got the English fallback on\n * every dialog it ever opened.\n */\n private closeLabel(): string {\n const resolved = this.i18n?.t('dialog.close');\n return !resolved || resolved === 'dialog.close' ? 'Close dialog' : resolved;\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive, ElementRef, inject } from '@angular/core';\n\nlet uid = 0;\n\n/**\n * Styles a dialog title row. Use on a heading inside an opened dialog.\n * Auto-assigns an `id` so the dialog panel can reference it via\n * `aria-labelledby`.\n *\n * @example\n * ```html\n * <h2 wrDialogTitle>Confirm delete</h2>\n * ```\n */\n@Directive({\n selector: '[wrDialogTitle]',\n host: { class: 'wr-dialog__title', '[attr.id]': 'id' },\n})\nexport class WrDialogTitle {\n /** Generated id used for `aria-labelledby` wiring. */\n readonly id = `wr-dialog-title-${++uid}`;\n\n /** @internal */\n readonly elementRef = inject(ElementRef<HTMLElement>);\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive } from '@angular/core';\n\n/**\n * Styles the scrollable body section of a dialog.\n *\n * @example\n * ```html\n * <div wrDialogContent>…body…</div>\n * ```\n */\n@Directive({\n selector: '[wrDialogContent]',\n host: { class: 'wr-dialog__content' },\n})\nexport class WrDialogContent {}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive, computed, input } from '@angular/core';\n\n/**\n * Footer row, typically holding action buttons.\n *\n * @example\n * ```html\n * <div wrDialogFooter align=\"end\">\n * <wr-btn wrDialogClose>Cancel</wr-btn>\n * <wr-btn color=\"danger\" (click)=\"confirm()\">Delete</wr-btn>\n * </div>\n * ```\n */\n@Directive({\n selector: '[wrDialogFooter]',\n host: { '[class]': 'classes()' },\n})\nexport class WrDialogFooter {\n /**\n * Horizontal alignment of the children.\n *\n * @default 'end'\n */\n readonly align = input<'start' | 'center' | 'end'>('end');\n\n protected readonly classes = computed(() => `wr-dialog__footer wr-dialog__footer--${this.align()}`);\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Directive, inject, input } from '@angular/core';\n\nimport type { WrDialogRef } from '../dialog-ref';\nimport { WR_DIALOG_REF } from '../tokens';\n\n/**\n * Closes the dialog when the host element is clicked.\n *\n * Optionally passes a `[wrDialogClose]` value as the close result.\n *\n * @example\n * ```html\n * <wr-btn wrDialogClose>Cancel</wr-btn>\n * <wr-btn color=\"primary\" [wrDialogClose]=\"true\">Confirm</wr-btn>\n * ```\n */\n@Directive({\n selector: '[wrDialogClose]',\n host: { '(click)': 'onClick()' },\n})\nexport class WrDialogClose<R = unknown> {\n /**\n * Value to pass to `close()`. When unset — or used as a bare attribute — the\n * dialog closes with `undefined`.\n */\n readonly result = input<R | undefined, R | undefined | ''>(undefined, {\n alias: 'wrDialogClose',\n // A bare `wrDialogClose` attribute arrives as the empty string; that means\n // \"no result\", not a result of `''`. Matches `wrDrawerClose`.\n transform: value => (value === '' ? undefined : value),\n });\n\n private readonly ref = inject<WrDialogRef<unknown, R>>(WR_DIALOG_REF, { optional: true });\n\n protected onClick(): void {\n this.ref?.close(this.result());\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -35,10 +35,10 @@ class WrAutofocus {
35
35
  }
36
36
  });
37
37
  }
38
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: WrAutofocus, deps: [], target: i0.ɵɵFactoryTarget.Directive });
39
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.0", type: WrAutofocus, isStandalone: true, selector: "[wrAutofocus]", inputs: { wrAutofocus: { classPropertyName: "wrAutofocus", publicName: "wrAutofocus", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
38
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: WrAutofocus, deps: [], target: i0.ɵɵFactoryTarget.Directive });
39
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.1", type: WrAutofocus, isStandalone: true, selector: "[wrAutofocus]", inputs: { wrAutofocus: { classPropertyName: "wrAutofocus", publicName: "wrAutofocus", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
40
40
  }
41
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: WrAutofocus, decorators: [{
41
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: WrAutofocus, decorators: [{
42
42
  type: Directive,
43
43
  args: [{ selector: '[wrAutofocus]' }]
44
44
  }], ctorParameters: () => [], propDecorators: { wrAutofocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "wrAutofocus", required: false }] }] } });
@@ -109,10 +109,10 @@ class WrAutosize {
109
109
  node.style.height = `${next}px`;
110
110
  node.style.overflowY = node.scrollHeight + border > max ? 'auto' : 'hidden';
111
111
  }
112
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: WrAutosize, deps: [], target: i0.ɵɵFactoryTarget.Directive });
113
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.0", type: WrAutosize, isStandalone: true, selector: "textarea[wrAutosize]", inputs: { minRows: { classPropertyName: "minRows", publicName: "minRows", isSignal: true, isRequired: false, transformFunction: null }, maxRows: { classPropertyName: "maxRows", publicName: "maxRows", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "input": "onInput()" }, styleAttribute: "overflow: hidden; resize: none;" }, ngImport: i0 });
112
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: WrAutosize, deps: [], target: i0.ɵɵFactoryTarget.Directive });
113
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.1", type: WrAutosize, isStandalone: true, selector: "textarea[wrAutosize]", inputs: { minRows: { classPropertyName: "minRows", publicName: "minRows", isSignal: true, isRequired: false, transformFunction: null }, maxRows: { classPropertyName: "maxRows", publicName: "maxRows", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "input": "onInput()" }, styleAttribute: "overflow: hidden; resize: none;" }, ngImport: i0 });
114
114
  }
115
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: WrAutosize, decorators: [{
115
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: WrAutosize, decorators: [{
116
116
  type: Directive,
117
117
  args: [{
118
118
  selector: 'textarea[wrAutosize]',
@@ -157,10 +157,10 @@ class WrClickOutside {
157
157
  });
158
158
  });
159
159
  }
160
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: WrClickOutside, deps: [], target: i0.ɵɵFactoryTarget.Directive });
161
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.0", type: WrClickOutside, isStandalone: true, selector: "[wrClickOutside]", outputs: { wrClickOutside: "wrClickOutside" }, ngImport: i0 });
160
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: WrClickOutside, deps: [], target: i0.ɵɵFactoryTarget.Directive });
161
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.1", type: WrClickOutside, isStandalone: true, selector: "[wrClickOutside]", outputs: { wrClickOutside: "wrClickOutside" }, ngImport: i0 });
162
162
  }
163
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: WrClickOutside, decorators: [{
163
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: WrClickOutside, decorators: [{
164
164
  type: Directive,
165
165
  args: [{ selector: '[wrClickOutside]' }]
166
166
  }], ctorParameters: () => [], propDecorators: { wrClickOutside: [{ type: i0.Output, args: ["wrClickOutside"] }] } });
@@ -195,26 +195,46 @@ class WrCopyToClipboard {
195
195
  /** @internal */
196
196
  async onClick() {
197
197
  const text = this.wrCopyToClipboard();
198
+ const async = this.doc.defaultView?.navigator?.clipboard;
198
199
  try {
199
- if (this.doc.defaultView?.navigator?.clipboard) {
200
- await this.doc.defaultView.navigator.clipboard.writeText(text);
200
+ if (async) {
201
+ try {
202
+ await async.writeText(text);
203
+ }
204
+ catch {
205
+ // The legacy path is a RECOVERY from the async one, so it only runs
206
+ // when there was an async attempt to recover from. Reached from the
207
+ // fallback's own failure it just repeated the same refused write —
208
+ // two selections and two focus jumps for one press.
209
+ this.fallback(text);
210
+ }
201
211
  }
202
212
  else {
203
213
  this.fallback(text);
204
214
  }
205
- this.copied.emit(text);
206
215
  }
207
216
  catch (error) {
208
- try {
209
- this.fallback(text);
210
- this.copied.emit(text);
211
- }
212
- catch (fallbackError) {
213
- this.copyFailed.emit(fallbackError ?? error);
214
- }
217
+ this.copyFailed.emit(error);
218
+ return;
215
219
  }
220
+ // Outside the try because the try's job is the WRITE. The shape this
221
+ // replaced emitted inside it and recovered by calling `fallback` again, so
222
+ // one refused write became two selections, two focus jumps and two `copied`
223
+ // emissions. (A consumer's own `(copied)` handler cannot reach this frame
224
+ // either way: `OutputEmitterRef.emit` catches what a listener throws and
225
+ // hands it to the `ErrorHandler`.)
226
+ this.copied.emit(text);
216
227
  }
217
- /** Legacy clipboard write — hidden textarea + execCommand('copy'). */
228
+ /**
229
+ * Legacy clipboard write — hidden textarea + `execCommand('copy')`.
230
+ *
231
+ * Two things this has to get right beyond writing the text. `execCommand`
232
+ * REPORTS refusal rather than throwing it: a document without focus hands back
233
+ * `false` and copies nothing, so ignoring the return value shows a "Copied!"
234
+ * toast over an unchanged clipboard. And selecting the textarea moves focus
235
+ * into it, so removing the node afterwards drops focus on `<body>` — the user's
236
+ * next Tab restarts from the top of the page, on every copy.
237
+ */
218
238
  fallback(text) {
219
239
  const node = this.doc.createElement('textarea');
220
240
  node.value = text;
@@ -224,19 +244,23 @@ class WrCopyToClipboard {
224
244
  node.style.left = '0';
225
245
  node.style.opacity = '0';
226
246
  node.style.pointerEvents = 'none';
247
+ const previous = this.doc.activeElement;
227
248
  this.doc.body.appendChild(node);
228
249
  node.select();
229
250
  try {
230
- this.doc.execCommand('copy');
251
+ if (!this.doc.execCommand('copy'))
252
+ throw new Error('The copy command was refused.');
231
253
  }
232
254
  finally {
233
255
  this.doc.body.removeChild(node);
256
+ if (previous instanceof HTMLElement)
257
+ previous.focus();
234
258
  }
235
259
  }
236
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: WrCopyToClipboard, deps: [], target: i0.ɵɵFactoryTarget.Directive });
237
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.0", type: WrCopyToClipboard, isStandalone: true, selector: "[wrCopyToClipboard]", inputs: { wrCopyToClipboard: { classPropertyName: "wrCopyToClipboard", publicName: "wrCopyToClipboard", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { copied: "copied", copyFailed: "copyFailed" }, host: { listeners: { "click": "onClick()" } }, ngImport: i0 });
260
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: WrCopyToClipboard, deps: [], target: i0.ɵɵFactoryTarget.Directive });
261
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.1", type: WrCopyToClipboard, isStandalone: true, selector: "[wrCopyToClipboard]", inputs: { wrCopyToClipboard: { classPropertyName: "wrCopyToClipboard", publicName: "wrCopyToClipboard", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { copied: "copied", copyFailed: "copyFailed" }, host: { listeners: { "click": "onClick()" } }, ngImport: i0 });
238
262
  }
239
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: WrCopyToClipboard, decorators: [{
263
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: WrCopyToClipboard, decorators: [{
240
264
  type: Directive,
241
265
  args: [{ selector: '[wrCopyToClipboard]', host: { '(click)': 'onClick()' } }]
242
266
  }], propDecorators: { wrCopyToClipboard: [{ type: i0.Input, args: [{ isSignal: true, alias: "wrCopyToClipboard", required: true }] }], copied: [{ type: i0.Output, args: ["copied"] }], copyFailed: [{ type: i0.Output, args: ["copyFailed"] }] } });
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-directives.mjs","sources":["../../../projects/lib/directives/autofocus.ts","../../../projects/lib/directives/autosize.ts","../../../projects/lib/directives/click-outside.ts","../../../projects/lib/directives/copy-to-clipboard.ts","../../../projects/lib/directives/ngwr-directives.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { Directive, ElementRef, afterNextRender, effect, inject, input } from '@angular/core';\n\n/**\n * Focus the host element after the first render — or whenever the bound\n * expression transitions to truthy.\n *\n * @example\n * ```html\n * <input wrAutofocus />\n * <input [wrAutofocus]=\"shouldFocus()\" />\n * ```\n */\n@Directive({ selector: '[wrAutofocus]' })\nexport class WrAutofocus {\n /** Truthy = focus. Defaults to `true` so bare `wrAutofocus` works. */\n readonly wrAutofocus = input(true, { transform: coerceBooleanProperty });\n\n private readonly el = inject<ElementRef<HTMLElement>>(ElementRef);\n\n constructor() {\n afterNextRender(() => {\n if (this.wrAutofocus()) this.el.nativeElement.focus();\n });\n effect(() => {\n if (this.wrAutofocus()) {\n // Microtask defer so view updates that flip the expression land first.\n queueMicrotask(() => this.el.nativeElement.focus());\n }\n });\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceNumberProperty } from '@angular/cdk/coercion';\nimport { isPlatformBrowser } from '@angular/common';\nimport { Directive, ElementRef, PLATFORM_ID, afterEveryRender, effect, inject, input } from '@angular/core';\n\n/**\n * Auto-grow a `<textarea>` to fit its content. Optional `minRows` /\n * `maxRows` bounds the height in rendered rows.\n *\n * @example\n * ```html\n * <textarea wrAutosize minRows=\"2\" maxRows=\"8\" [(ngModel)]=\"text\"></textarea>\n * ```\n */\n@Directive({\n selector: 'textarea[wrAutosize]',\n host: { style: 'overflow: hidden; resize: none;', '(input)': 'onInput()' },\n})\nexport class WrAutosize {\n readonly minRows = input(1, { transform: (v: unknown): number => Math.max(1, coerceNumberProperty(v, 1)) });\n readonly maxRows = input(0, { transform: (v: unknown): number => Math.max(0, coerceNumberProperty(v, 0)) });\n\n private readonly el = inject<ElementRef<HTMLTextAreaElement>>(ElementRef);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n private lastValue: string | null = null;\n\n constructor() {\n // Typing fires `input`, but `[(ngModel)]` / `setValue` write the value\n // without one — a cheap per-render value check catches both, including\n // the initial write that lands after the first render.\n afterEveryRender(() => {\n const value = this.el.nativeElement.value;\n if (value !== this.lastValue) {\n this.lastValue = value;\n this.resize();\n }\n });\n // Resize when `minRows` / `maxRows` change. Read the inputs before the\n // platform check so the effect still tracks them; the measurement itself\n // needs a real layout, which the server has none of (`afterEveryRender`\n // above is browser-only already, so it needs no guard).\n effect(() => {\n this.minRows();\n this.maxRows();\n if (!this.isBrowser) return;\n this.resize();\n });\n }\n\n /** @internal */\n protected onInput(): void {\n this.lastValue = this.el.nativeElement.value;\n this.resize();\n }\n\n /** Recompute height from `scrollHeight`, clamped to min/max rows. */\n private resize(): void {\n const node = this.el.nativeElement;\n const styles = getComputedStyle(node);\n // `line-height: normal` computes to the literal string — derive the\n // row height from the font size instead of guessing a fixed 20px.\n const lineHeight = parseFloat(styles.lineHeight) || parseFloat(styles.fontSize) * 1.25 || 20;\n const paddingY = parseFloat(styles.paddingTop) + parseFloat(styles.paddingBottom);\n const border = (parseFloat(styles.borderTopWidth) || 0) + (parseFloat(styles.borderBottomWidth) || 0);\n\n // Reset to a single row first so `scrollHeight` shrinks as well as grows.\n node.style.height = 'auto';\n const min = this.minRows() * lineHeight + paddingY + border;\n const max = this.maxRows() > 0 ? this.maxRows() * lineHeight + paddingY + border : Infinity;\n const next = Math.min(Math.max(node.scrollHeight + border, min), max);\n node.style.height = `${next}px`;\n node.style.overflowY = node.scrollHeight + border > max ? 'auto' : 'hidden';\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { DOCUMENT } from '@angular/common';\nimport { DestroyRef, Directive, ElementRef, NgZone, inject, output } from '@angular/core';\n\n/**\n * Fires `(wrClickOutside)` when a pointer event lands outside the host\n * element. Useful for closing custom poppers / menus.\n *\n * @example\n * ```html\n * <div class=\"popup\" (wrClickOutside)=\"close()\"> … </div>\n * ```\n */\n@Directive({ selector: '[wrClickOutside]' })\nexport class WrClickOutside {\n readonly wrClickOutside = output<MouseEvent>();\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly doc = inject(DOCUMENT);\n private readonly zone = inject(NgZone);\n private readonly destroyRef = inject(DestroyRef);\n\n constructor() {\n // Listen outside Angular to avoid CD on every page click; re-enter\n // only when the event lands outside the host.\n this.zone.runOutsideAngular(() => {\n const handler = (event: MouseEvent): void => {\n const target = event.target as Node | null;\n if (target && !this.host.nativeElement.contains(target)) {\n this.zone.run(() => this.wrClickOutside.emit(event));\n }\n };\n this.doc.addEventListener('mousedown', handler, true);\n this.destroyRef.onDestroy(() => {\n this.doc.removeEventListener('mousedown', handler, true);\n });\n });\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { DOCUMENT } from '@angular/common';\nimport { Directive, inject, input, output } from '@angular/core';\n\n/**\n * Copy `wrCopyToClipboard` to the system clipboard on host click.\n *\n * Uses `navigator.clipboard.writeText` when available, with a hidden\n * `<textarea>` + `document.execCommand('copy')` fallback for older browsers\n * and non-secure contexts.\n *\n * @example\n * ```html\n * <button [wrCopyToClipboard]=\"value\" (copied)=\"toast('Copied!')\">Copy</button>\n * ```\n */\n@Directive({ selector: '[wrCopyToClipboard]', host: { '(click)': 'onClick()' } })\nexport class WrCopyToClipboard {\n /** The text to copy. */\n readonly wrCopyToClipboard = input.required<string>();\n\n /** Emitted with the copied text once the write succeeds. */\n readonly copied = output<string>();\n\n /** Emitted if the copy fails (denied permission, no clipboard, …). */\n readonly copyFailed = output<unknown>();\n\n private readonly doc = inject(DOCUMENT);\n\n /** @internal */\n protected async onClick(): Promise<void> {\n const text = this.wrCopyToClipboard();\n try {\n if (this.doc.defaultView?.navigator?.clipboard) {\n await this.doc.defaultView.navigator.clipboard.writeText(text);\n } else {\n this.fallback(text);\n }\n this.copied.emit(text);\n } catch (error) {\n try {\n this.fallback(text);\n this.copied.emit(text);\n } catch (fallbackError) {\n this.copyFailed.emit(fallbackError ?? error);\n }\n }\n }\n\n /** Legacy clipboard write — hidden textarea + execCommand('copy'). */\n private fallback(text: string): void {\n const node = this.doc.createElement('textarea');\n node.value = text;\n node.setAttribute('readonly', '');\n node.style.position = 'fixed';\n node.style.top = '0';\n node.style.left = '0';\n node.style.opacity = '0';\n node.style.pointerEvents = 'none';\n this.doc.body.appendChild(node);\n node.select();\n try {\n this.doc.execCommand('copy');\n } finally {\n this.doc.body.removeChild(node);\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngwr-directives.mjs","sources":["../../../projects/lib/directives/autofocus.ts","../../../projects/lib/directives/autosize.ts","../../../projects/lib/directives/click-outside.ts","../../../projects/lib/directives/copy-to-clipboard.ts","../../../projects/lib/directives/ngwr-directives.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { Directive, ElementRef, afterNextRender, effect, inject, input } from '@angular/core';\n\n/**\n * Focus the host element after the first render — or whenever the bound\n * expression transitions to truthy.\n *\n * @example\n * ```html\n * <input wrAutofocus />\n * <input [wrAutofocus]=\"shouldFocus()\" />\n * ```\n */\n@Directive({ selector: '[wrAutofocus]' })\nexport class WrAutofocus {\n /** Truthy = focus. Defaults to `true` so bare `wrAutofocus` works. */\n readonly wrAutofocus = input(true, { transform: coerceBooleanProperty });\n\n private readonly el = inject<ElementRef<HTMLElement>>(ElementRef);\n\n constructor() {\n afterNextRender(() => {\n if (this.wrAutofocus()) this.el.nativeElement.focus();\n });\n effect(() => {\n if (this.wrAutofocus()) {\n // Microtask defer so view updates that flip the expression land first.\n queueMicrotask(() => this.el.nativeElement.focus());\n }\n });\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceNumberProperty } from '@angular/cdk/coercion';\nimport { isPlatformBrowser } from '@angular/common';\nimport { Directive, ElementRef, PLATFORM_ID, afterEveryRender, effect, inject, input } from '@angular/core';\n\n/**\n * Auto-grow a `<textarea>` to fit its content. Optional `minRows` /\n * `maxRows` bounds the height in rendered rows.\n *\n * @example\n * ```html\n * <textarea wrAutosize minRows=\"2\" maxRows=\"8\" [(ngModel)]=\"text\"></textarea>\n * ```\n */\n@Directive({\n selector: 'textarea[wrAutosize]',\n host: { style: 'overflow: hidden; resize: none;', '(input)': 'onInput()' },\n})\nexport class WrAutosize {\n readonly minRows = input(1, { transform: (v: unknown): number => Math.max(1, coerceNumberProperty(v, 1)) });\n readonly maxRows = input(0, { transform: (v: unknown): number => Math.max(0, coerceNumberProperty(v, 0)) });\n\n private readonly el = inject<ElementRef<HTMLTextAreaElement>>(ElementRef);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n private lastValue: string | null = null;\n\n constructor() {\n // Typing fires `input`, but `[(ngModel)]` / `setValue` write the value\n // without one — a cheap per-render value check catches both, including\n // the initial write that lands after the first render.\n afterEveryRender(() => {\n const value = this.el.nativeElement.value;\n if (value !== this.lastValue) {\n this.lastValue = value;\n this.resize();\n }\n });\n // Resize when `minRows` / `maxRows` change. Read the inputs before the\n // platform check so the effect still tracks them; the measurement itself\n // needs a real layout, which the server has none of (`afterEveryRender`\n // above is browser-only already, so it needs no guard).\n effect(() => {\n this.minRows();\n this.maxRows();\n if (!this.isBrowser) return;\n this.resize();\n });\n }\n\n /** @internal */\n protected onInput(): void {\n this.lastValue = this.el.nativeElement.value;\n this.resize();\n }\n\n /** Recompute height from `scrollHeight`, clamped to min/max rows. */\n private resize(): void {\n const node = this.el.nativeElement;\n const styles = getComputedStyle(node);\n // `line-height: normal` computes to the literal string — derive the\n // row height from the font size instead of guessing a fixed 20px.\n const lineHeight = parseFloat(styles.lineHeight) || parseFloat(styles.fontSize) * 1.25 || 20;\n const paddingY = parseFloat(styles.paddingTop) + parseFloat(styles.paddingBottom);\n const border = (parseFloat(styles.borderTopWidth) || 0) + (parseFloat(styles.borderBottomWidth) || 0);\n\n // Reset to a single row first so `scrollHeight` shrinks as well as grows.\n node.style.height = 'auto';\n const min = this.minRows() * lineHeight + paddingY + border;\n const max = this.maxRows() > 0 ? this.maxRows() * lineHeight + paddingY + border : Infinity;\n const next = Math.min(Math.max(node.scrollHeight + border, min), max);\n node.style.height = `${next}px`;\n node.style.overflowY = node.scrollHeight + border > max ? 'auto' : 'hidden';\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { DOCUMENT } from '@angular/common';\nimport { DestroyRef, Directive, ElementRef, NgZone, inject, output } from '@angular/core';\n\n/**\n * Fires `(wrClickOutside)` when a pointer event lands outside the host\n * element. Useful for closing custom poppers / menus.\n *\n * @example\n * ```html\n * <div class=\"popup\" (wrClickOutside)=\"close()\"> … </div>\n * ```\n */\n@Directive({ selector: '[wrClickOutside]' })\nexport class WrClickOutside {\n readonly wrClickOutside = output<MouseEvent>();\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly doc = inject(DOCUMENT);\n private readonly zone = inject(NgZone);\n private readonly destroyRef = inject(DestroyRef);\n\n constructor() {\n // Listen outside Angular to avoid CD on every page click; re-enter\n // only when the event lands outside the host.\n this.zone.runOutsideAngular(() => {\n const handler = (event: MouseEvent): void => {\n const target = event.target as Node | null;\n if (target && !this.host.nativeElement.contains(target)) {\n this.zone.run(() => this.wrClickOutside.emit(event));\n }\n };\n this.doc.addEventListener('mousedown', handler, true);\n this.destroyRef.onDestroy(() => {\n this.doc.removeEventListener('mousedown', handler, true);\n });\n });\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { DOCUMENT } from '@angular/common';\nimport { Directive, inject, input, output } from '@angular/core';\n\n/**\n * Copy `wrCopyToClipboard` to the system clipboard on host click.\n *\n * Uses `navigator.clipboard.writeText` when available, with a hidden\n * `<textarea>` + `document.execCommand('copy')` fallback for older browsers\n * and non-secure contexts.\n *\n * @example\n * ```html\n * <button [wrCopyToClipboard]=\"value\" (copied)=\"toast('Copied!')\">Copy</button>\n * ```\n */\n@Directive({ selector: '[wrCopyToClipboard]', host: { '(click)': 'onClick()' } })\nexport class WrCopyToClipboard {\n /** The text to copy. */\n readonly wrCopyToClipboard = input.required<string>();\n\n /** Emitted with the copied text once the write succeeds. */\n readonly copied = output<string>();\n\n /** Emitted if the copy fails (denied permission, no clipboard, …). */\n readonly copyFailed = output<unknown>();\n\n private readonly doc = inject(DOCUMENT);\n\n /** @internal */\n protected async onClick(): Promise<void> {\n const text = this.wrCopyToClipboard();\n const async = this.doc.defaultView?.navigator?.clipboard;\n\n try {\n if (async) {\n try {\n await async.writeText(text);\n } catch {\n // The legacy path is a RECOVERY from the async one, so it only runs\n // when there was an async attempt to recover from. Reached from the\n // fallback's own failure it just repeated the same refused write —\n // two selections and two focus jumps for one press.\n this.fallback(text);\n }\n } else {\n this.fallback(text);\n }\n } catch (error) {\n this.copyFailed.emit(error);\n return;\n }\n\n // Outside the try because the try's job is the WRITE. The shape this\n // replaced emitted inside it and recovered by calling `fallback` again, so\n // one refused write became two selections, two focus jumps and two `copied`\n // emissions. (A consumer's own `(copied)` handler cannot reach this frame\n // either way: `OutputEmitterRef.emit` catches what a listener throws and\n // hands it to the `ErrorHandler`.)\n this.copied.emit(text);\n }\n\n /**\n * Legacy clipboard write — hidden textarea + `execCommand('copy')`.\n *\n * Two things this has to get right beyond writing the text. `execCommand`\n * REPORTS refusal rather than throwing it: a document without focus hands back\n * `false` and copies nothing, so ignoring the return value shows a \"Copied!\"\n * toast over an unchanged clipboard. And selecting the textarea moves focus\n * into it, so removing the node afterwards drops focus on `<body>` — the user's\n * next Tab restarts from the top of the page, on every copy.\n */\n private fallback(text: string): void {\n const node = this.doc.createElement('textarea');\n node.value = text;\n node.setAttribute('readonly', '');\n node.style.position = 'fixed';\n node.style.top = '0';\n node.style.left = '0';\n node.style.opacity = '0';\n node.style.pointerEvents = 'none';\n\n const previous = this.doc.activeElement;\n this.doc.body.appendChild(node);\n node.select();\n\n try {\n if (!this.doc.execCommand('copy')) throw new Error('The copy command was refused.');\n } finally {\n this.doc.body.removeChild(node);\n if (previous instanceof HTMLElement) previous.focus();\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;AAAA;;;;;AAKG;AAKH;;;;;;;;;AASG;MAEU,WAAW,CAAA;;IAEb,WAAW,GAAG,KAAK,CAAC,IAAI,mFAAI,SAAS,EAAE,qBAAqB,EAAA,CAAG;AAEvD,IAAA,EAAE,GAAG,MAAM,CAA0B,UAAU,CAAC;AAEjE,IAAA,WAAA,GAAA;QACE,eAAe,CAAC,MAAK;YACnB,IAAI,IAAI,CAAC,WAAW,EAAE;AAAE,gBAAA,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK,EAAE;AACvD,QAAA,CAAC,CAAC;QACF,MAAM,CAAC,MAAK;AACV,YAAA,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE;;AAEtB,gBAAA,cAAc,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;YACrD;AACF,QAAA,CAAC,CAAC;IACJ;uGAhBW,WAAW,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAX,WAAW,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAX,WAAW,EAAA,UAAA,EAAA,CAAA;kBADvB,SAAS;mBAAC,EAAE,QAAQ,EAAE,eAAe,EAAE;;;ACpBxC;;;;;AAKG;AAMH;;;;;;;;AAQG;MAKU,UAAU,CAAA;IACZ,OAAO,GAAG,KAAK,CAAC,CAAC,EAAA,EAAA,IAAA,SAAA,GAAA,EAAA,SAAA,EAAA,SAAA,EAAA,8BAAA,EAAA,CAAA,EAAI,SAAS,EAAE,CAAC,CAAU,KAAa,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAA,CAAG;IAClG,OAAO,GAAG,KAAK,CAAC,CAAC,EAAA,EAAA,IAAA,SAAA,GAAA,EAAA,SAAA,EAAA,SAAA,EAAA,8BAAA,EAAA,CAAA,EAAI,SAAS,EAAE,CAAC,CAAU,KAAa,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAA,CAAG;AAE1F,IAAA,EAAE,GAAG,MAAM,CAAkC,UAAU,CAAC;IACxD,SAAS,GAAG,iBAAiB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAE3D,SAAS,GAAkB,IAAI;AAEvC,IAAA,WAAA,GAAA;;;;QAIE,gBAAgB,CAAC,MAAK;YACpB,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK;AACzC,YAAA,IAAI,KAAK,KAAK,IAAI,CAAC,SAAS,EAAE;AAC5B,gBAAA,IAAI,CAAC,SAAS,GAAG,KAAK;gBACtB,IAAI,CAAC,MAAM,EAAE;YACf;AACF,QAAA,CAAC,CAAC;;;;;QAKF,MAAM,CAAC,MAAK;YACV,IAAI,CAAC,OAAO,EAAE;YACd,IAAI,CAAC,OAAO,EAAE;YACd,IAAI,CAAC,IAAI,CAAC,SAAS;gBAAE;YACrB,IAAI,CAAC,MAAM,EAAE;AACf,QAAA,CAAC,CAAC;IACJ;;IAGU,OAAO,GAAA;QACf,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK;QAC5C,IAAI,CAAC,MAAM,EAAE;IACf;;IAGQ,MAAM,GAAA;AACZ,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,aAAa;AAClC,QAAA,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC;;;AAGrC,QAAA,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,IAAI,IAAI,EAAE;AAC5F,QAAA,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,aAAa,CAAC;QACjF,MAAM,MAAM,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,UAAU,CAAC,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;;AAGrG,QAAA,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM;AAC1B,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,UAAU,GAAG,QAAQ,GAAG,MAAM;QAC3D,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,UAAU,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ;QAC3F,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,GAAG,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC;QACrE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAA,EAAG,IAAI,IAAI;QAC/B,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,YAAY,GAAG,MAAM,GAAG,GAAG,GAAG,MAAM,GAAG,QAAQ;IAC7E;uGAvDW,UAAU,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAV,UAAU,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,sBAAA,EAAA,MAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,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,cAAA,EAAA,iCAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAV,UAAU,EAAA,UAAA,EAAA,CAAA;kBAJtB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,sBAAsB;oBAChC,IAAI,EAAE,EAAE,KAAK,EAAE,iCAAiC,EAAE,SAAS,EAAE,WAAW,EAAE;AAC3E,iBAAA;;;ACvBD;;;;;AAKG;AAKH;;;;;;;;AAQG;MAEU,cAAc,CAAA;IAChB,cAAc,GAAG,MAAM,EAAc;AAE7B,IAAA,IAAI,GAAG,MAAM,CAA0B,UAAU,CAAC;AAClD,IAAA,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC;AACtB,IAAA,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC;AACrB,IAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AAEhD,IAAA,WAAA,GAAA;;;AAGE,QAAA,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAK;AAC/B,YAAA,MAAM,OAAO,GAAG,CAAC,KAAiB,KAAU;AAC1C,gBAAA,MAAM,MAAM,GAAG,KAAK,CAAC,MAAqB;AAC1C,gBAAA,IAAI,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;AACvD,oBAAA,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACtD;AACF,YAAA,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,WAAW,EAAE,OAAO,EAAE,IAAI,CAAC;AACrD,YAAA,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAK;gBAC7B,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC,WAAW,EAAE,OAAO,EAAE,IAAI,CAAC;AAC1D,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;uGAvBW,cAAc,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAd,cAAc,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,OAAA,EAAA,EAAA,cAAA,EAAA,gBAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAd,cAAc,EAAA,UAAA,EAAA,CAAA;kBAD1B,SAAS;mBAAC,EAAE,QAAQ,EAAE,kBAAkB,EAAE;;;ACnB3C;;;;;AAKG;AAKH;;;;;;;;;;;AAWG;MAEU,iBAAiB,CAAA;;IAEnB,iBAAiB,GAAG,KAAK,CAAC,QAAQ;0FAAU;;IAG5C,MAAM,GAAG,MAAM,EAAU;;IAGzB,UAAU,GAAG,MAAM,EAAW;AAEtB,IAAA,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC;;AAG7B,IAAA,MAAM,OAAO,GAAA;AACrB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,EAAE;QACrC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,SAAS,EAAE,SAAS;AAExD,QAAA,IAAI;YACF,IAAI,KAAK,EAAE;AACT,gBAAA,IAAI;AACF,oBAAA,MAAM,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC;gBAC7B;AAAE,gBAAA,MAAM;;;;;AAKN,oBAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;gBACrB;YACF;iBAAO;AACL,gBAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YACrB;QACF;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC;YAC3B;QACF;;;;;;;AAQA,QAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;IACxB;AAEA;;;;;;;;;AASG;AACK,IAAA,QAAQ,CAAC,IAAY,EAAA;QAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,UAAU,CAAC;AAC/C,QAAA,IAAI,CAAC,KAAK,GAAG,IAAI;AACjB,QAAA,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,EAAE,CAAC;AACjC,QAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO;AAC7B,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG;AACpB,QAAA,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG;AACrB,QAAA,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,GAAG;AACxB,QAAA,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,MAAM;AAEjC,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa;QACvC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;QAC/B,IAAI,CAAC,MAAM,EAAE;AAEb,QAAA,IAAI;YACF,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC;AAAE,gBAAA,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC;QACrF;gBAAU;YACR,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;YAC/B,IAAI,QAAQ,YAAY,WAAW;gBAAE,QAAQ,CAAC,KAAK,EAAE;QACvD;IACF;uGA3EW,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAjB,iBAAiB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,qBAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,EAAA,iBAAA,EAAA,mBAAA,EAAA,UAAA,EAAA,mBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,MAAA,EAAA,QAAA,EAAA,UAAA,EAAA,YAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,OAAA,EAAA,WAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAjB,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAD7B,SAAS;mBAAC,EAAE,QAAQ,EAAE,qBAAqB,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE;;;ACtBhF;;AAEG;;;;"}
@@ -63,10 +63,10 @@ class WrDivider {
63
63
  return parts.join(' ');
64
64
  }, /* @ts-ignore */
65
65
  ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
66
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: WrDivider, deps: [], target: i0.ɵɵFactoryTarget.Component });
67
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.0", type: WrDivider, isStandalone: true, selector: "wr-divider", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "separator" }, properties: { "class": "classes()", "style.--wr-divider-width.px": "width()" } }, ngImport: i0, template: '<ng-content />', isInline: true, encapsulation: i0.ViewEncapsulation.None });
66
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: WrDivider, deps: [], target: i0.ɵɵFactoryTarget.Component });
67
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.1", type: WrDivider, isStandalone: true, selector: "wr-divider", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "separator" }, properties: { "class": "classes()", "style.--wr-divider-width.px": "width()" } }, ngImport: i0, template: '<ng-content />', isInline: true, encapsulation: i0.ViewEncapsulation.None });
68
68
  }
69
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: WrDivider, decorators: [{
69
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: WrDivider, decorators: [{
70
70
  type: Component,
71
71
  args: [{
72
72
  selector: 'wr-divider',
@@ -1,6 +1,7 @@
1
1
  import { coerceNumberProperty, coerceBooleanProperty } from '@angular/cdk/coercion';
2
2
  import * as i0 from '@angular/core';
3
3
  import { input, computed, ViewEncapsulation, Component } from '@angular/core';
4
+ import { useI18nText } from 'ngwr/i18n';
4
5
 
5
6
  /**
6
7
  * @license
@@ -8,6 +9,14 @@ import { input, computed, ViewEncapsulation, Component } from '@angular/core';
8
9
  * Use of this source code is governed by an MIT-style license that can be
9
10
  * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
10
11
  */
12
+ /**
13
+ * A segment's contribution to the ring. `Math.max(0, NaN)` is NaN, and the running total
14
+ * carries it forward — so one non-finite datum used to take out its own arc AND every arc
15
+ * after it, writing the literal text `NaN` into the path `d`.
16
+ */
17
+ function weight(value) {
18
+ return Number.isFinite(value) ? Math.max(0, value) : 0;
19
+ }
11
20
  const FALLBACK_COLORS = [
12
21
  'var(--wr-color-primary)',
13
22
  'var(--wr-color-secondary)',
@@ -33,6 +42,14 @@ const FALLBACK_COLORS = [
33
42
  class WrDonutChart {
34
43
  segments = input([], /* @ts-ignore */
35
44
  ...(ngDevMode ? [{ debugName: "segments" }] : /* istanbul ignore next */ []));
45
+ /**
46
+ * Accessible name of the chart. The ring is `aria-hidden` and the legend is optional,
47
+ * so with `showLegend: false` this is the only thing a screen reader gets. Falls back
48
+ * to `donutChart.label`.
49
+ */
50
+ ariaLabel = input(null, /* @ts-ignore */
51
+ ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
52
+ resolvedAriaLabel = useI18nText(this.ariaLabel, 'donutChart.label', 'Donut chart');
36
53
  /** Diameter in CSS pixels. @default 200 */
37
54
  size = input(200, { ...(ngDevMode ? { debugName: "size" } : /* istanbul ignore next */ {}), transform: (v) => Math.max(48, coerceNumberProperty(v, 200)) });
38
55
  /** Inner-ring thickness as a percent of radius (0–100). `0` = solid pie. @default 30 */
@@ -56,7 +73,7 @@ class WrDonutChart {
56
73
  }, /* @ts-ignore */
57
74
  ...(ngDevMode ? [{ debugName: "innerR" }] : /* istanbul ignore next */ []));
58
75
  total = computed(() => {
59
- const sum = this.segments().reduce((acc, s) => acc + Math.max(0, s.value), 0);
76
+ const sum = this.segments().reduce((acc, s) => acc + weight(s.value), 0);
60
77
  return sum > 0 ? sum : 1;
61
78
  }, /* @ts-ignore */
62
79
  ...(ngDevMode ? [{ debugName: "total" }] : /* istanbul ignore next */ []));
@@ -65,7 +82,7 @@ class WrDonutChart {
65
82
  const total = this.total();
66
83
  let cumulative = 0;
67
84
  return this.segments().map((s, i) => {
68
- const value = Math.max(0, s.value);
85
+ const value = weight(s.value);
69
86
  const startAngle = (cumulative / total) * Math.PI * 2;
70
87
  cumulative += value;
71
88
  const endAngle = (cumulative / total) * Math.PI * 2;
@@ -121,13 +138,13 @@ class WrDonutChart {
121
138
  'Z',
122
139
  ].join(' ');
123
140
  }
124
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: WrDonutChart, deps: [], target: i0.ɵɵFactoryTarget.Component });
125
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: WrDonutChart, isStandalone: true, selector: "wr-donut-chart", inputs: { segments: { classPropertyName: "segments", publicName: "segments", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, thickness: { classPropertyName: "thickness", publicName: "thickness", isSignal: true, isRequired: false, transformFunction: null }, showLegend: { classPropertyName: "showLegend", publicName: "showLegend", isSignal: true, isRequired: false, transformFunction: null }, centerValue: { classPropertyName: "centerValue", publicName: "centerValue", isSignal: true, isRequired: false, transformFunction: null }, centerLabel: { classPropertyName: "centerLabel", publicName: "centerLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "wr-donut-chart" }, ngImport: i0, template: "<div class=\"wr-donut-chart__surface\" [style.width.px]=\"size()\">\n <svg viewBox=\"0 0 100 100\" aria-hidden=\"true\">\n @for (slice of slices(); track $index) {\n <path [attr.d]=\"slice.path\" [attr.fill]=\"slice.color\" />\n }\n </svg>\n @if (centerValue() || centerLabel()) {\n <div class=\"wr-donut-chart__center\">\n @if (centerValue()) {\n <div class=\"wr-donut-chart__center-value\">{{ centerValue() }}</div>\n }\n @if (centerLabel()) {\n <div class=\"wr-donut-chart__center-label\">{{ centerLabel() }}</div>\n }\n </div>\n }\n</div>\n\n@if (showLegend()) {\n <ul class=\"wr-donut-chart__legend\">\n @for (slice of slices(); track $index) {\n <li class=\"wr-donut-chart__legend-item\">\n <span class=\"wr-donut-chart__swatch\" [style.background]=\"slice.color\"></span>\n <span class=\"wr-donut-chart__legend-label\">{{ slice.label }}</span>\n <span class=\"wr-donut-chart__legend-value\">{{ slice.value }}</span>\n </li>\n }\n </ul>\n}\n", encapsulation: i0.ViewEncapsulation.None });
141
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: WrDonutChart, deps: [], target: i0.ɵɵFactoryTarget.Component });
142
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.1", type: WrDonutChart, isStandalone: true, selector: "wr-donut-chart", inputs: { segments: { classPropertyName: "segments", publicName: "segments", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, thickness: { classPropertyName: "thickness", publicName: "thickness", isSignal: true, isRequired: false, transformFunction: null }, showLegend: { classPropertyName: "showLegend", publicName: "showLegend", isSignal: true, isRequired: false, transformFunction: null }, centerValue: { classPropertyName: "centerValue", publicName: "centerValue", isSignal: true, isRequired: false, transformFunction: null }, centerLabel: { classPropertyName: "centerLabel", publicName: "centerLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "wr-donut-chart" }, ngImport: i0, template: "<div class=\"wr-donut-chart__surface\" role=\"img\" [attr.aria-label]=\"resolvedAriaLabel()\" [style.width.px]=\"size()\">\n <svg viewBox=\"0 0 100 100\" aria-hidden=\"true\">\n @for (slice of slices(); track $index) {\n <path [attr.d]=\"slice.path\" [attr.fill]=\"slice.color\" />\n }\n </svg>\n @if (centerValue() || centerLabel()) {\n <div class=\"wr-donut-chart__center\">\n @if (centerValue()) {\n <div class=\"wr-donut-chart__center-value\">{{ centerValue() }}</div>\n }\n @if (centerLabel()) {\n <div class=\"wr-donut-chart__center-label\">{{ centerLabel() }}</div>\n }\n </div>\n }\n</div>\n\n@if (showLegend() && slices().length > 0) {\n <ul class=\"wr-donut-chart__legend\">\n @for (slice of slices(); track $index) {\n <li class=\"wr-donut-chart__legend-item\">\n <span class=\"wr-donut-chart__swatch\" [style.background]=\"slice.color\"></span>\n <span class=\"wr-donut-chart__legend-label\">{{ slice.label }}</span>\n <span class=\"wr-donut-chart__legend-value\">{{ slice.value }}</span>\n </li>\n }\n </ul>\n}\n", encapsulation: i0.ViewEncapsulation.None });
126
143
  }
127
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: WrDonutChart, decorators: [{
144
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: WrDonutChart, decorators: [{
128
145
  type: Component,
129
- args: [{ selector: 'wr-donut-chart', encapsulation: ViewEncapsulation.None, host: { class: 'wr-donut-chart' }, template: "<div class=\"wr-donut-chart__surface\" [style.width.px]=\"size()\">\n <svg viewBox=\"0 0 100 100\" aria-hidden=\"true\">\n @for (slice of slices(); track $index) {\n <path [attr.d]=\"slice.path\" [attr.fill]=\"slice.color\" />\n }\n </svg>\n @if (centerValue() || centerLabel()) {\n <div class=\"wr-donut-chart__center\">\n @if (centerValue()) {\n <div class=\"wr-donut-chart__center-value\">{{ centerValue() }}</div>\n }\n @if (centerLabel()) {\n <div class=\"wr-donut-chart__center-label\">{{ centerLabel() }}</div>\n }\n </div>\n }\n</div>\n\n@if (showLegend()) {\n <ul class=\"wr-donut-chart__legend\">\n @for (slice of slices(); track $index) {\n <li class=\"wr-donut-chart__legend-item\">\n <span class=\"wr-donut-chart__swatch\" [style.background]=\"slice.color\"></span>\n <span class=\"wr-donut-chart__legend-label\">{{ slice.label }}</span>\n <span class=\"wr-donut-chart__legend-value\">{{ slice.value }}</span>\n </li>\n }\n </ul>\n}\n" }]
130
- }], propDecorators: { segments: [{ type: i0.Input, args: [{ isSignal: true, alias: "segments", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], thickness: [{ type: i0.Input, args: [{ isSignal: true, alias: "thickness", required: false }] }], showLegend: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLegend", required: false }] }], centerValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "centerValue", required: false }] }], centerLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "centerLabel", required: false }] }] } });
146
+ args: [{ selector: 'wr-donut-chart', encapsulation: ViewEncapsulation.None, host: { class: 'wr-donut-chart' }, template: "<div class=\"wr-donut-chart__surface\" role=\"img\" [attr.aria-label]=\"resolvedAriaLabel()\" [style.width.px]=\"size()\">\n <svg viewBox=\"0 0 100 100\" aria-hidden=\"true\">\n @for (slice of slices(); track $index) {\n <path [attr.d]=\"slice.path\" [attr.fill]=\"slice.color\" />\n }\n </svg>\n @if (centerValue() || centerLabel()) {\n <div class=\"wr-donut-chart__center\">\n @if (centerValue()) {\n <div class=\"wr-donut-chart__center-value\">{{ centerValue() }}</div>\n }\n @if (centerLabel()) {\n <div class=\"wr-donut-chart__center-label\">{{ centerLabel() }}</div>\n }\n </div>\n }\n</div>\n\n@if (showLegend() && slices().length > 0) {\n <ul class=\"wr-donut-chart__legend\">\n @for (slice of slices(); track $index) {\n <li class=\"wr-donut-chart__legend-item\">\n <span class=\"wr-donut-chart__swatch\" [style.background]=\"slice.color\"></span>\n <span class=\"wr-donut-chart__legend-label\">{{ slice.label }}</span>\n <span class=\"wr-donut-chart__legend-value\">{{ slice.value }}</span>\n </li>\n }\n </ul>\n}\n" }]
147
+ }], propDecorators: { segments: [{ type: i0.Input, args: [{ isSignal: true, alias: "segments", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], thickness: [{ type: i0.Input, args: [{ isSignal: true, alias: "thickness", required: false }] }], showLegend: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLegend", required: false }] }], centerValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "centerValue", required: false }] }], centerLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "centerLabel", required: false }] }] } });
131
148
 
132
149
  /**
133
150
  * Generated bundle index. Do not edit.
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-donut-chart.mjs","sources":["../../../projects/lib/donut-chart/donut-chart.ts","../../../projects/lib/donut-chart/donut-chart.html","../../../projects/lib/donut-chart/ngwr-donut-chart.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';\nimport { Component, ViewEncapsulation, computed, input } from '@angular/core';\n\nimport type { WrDonutSegment } from './interfaces';\n\nconst FALLBACK_COLORS = [\n 'var(--wr-color-primary)',\n 'var(--wr-color-secondary)',\n 'var(--wr-color-success)',\n 'var(--wr-color-warning)',\n 'var(--wr-color-danger)',\n 'var(--wr-color-medium)',\n];\n\n/**\n * Donut chart. Set `thickness` to 0 for a solid pie. Optional center\n * text via inputs.\n *\n * @example\n * ```html\n * <wr-donut-chart [segments]=\"[\n * { label: 'Used', value: 60 },\n * { label: 'Free', value: 40 }\n * ]\" centerLabel=\"Disk\" centerValue=\"60%\" />\n * ```\n *\n * @see https://ngwr.dev/reference/components/donut-chart\n */\n@Component({\n selector: 'wr-donut-chart',\n templateUrl: './donut-chart.html',\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-donut-chart' },\n})\nexport class WrDonutChart {\n readonly segments = input<readonly WrDonutSegment[]>([]);\n\n /** Diameter in CSS pixels. @default 200 */\n readonly size = input(200, { transform: (v: unknown): number => Math.max(48, coerceNumberProperty(v, 200)) });\n\n /** Inner-ring thickness as a percent of radius (0–100). `0` = solid pie. @default 30 */\n readonly thickness = input(30, {\n transform: (v: unknown): number => Math.min(100, Math.max(0, coerceNumberProperty(v, 30))),\n });\n\n /** Show the legend under the chart. @default true */\n readonly showLegend = input(true, { transform: coerceBooleanProperty });\n\n /** Bold value text in the center. */\n readonly centerValue = input<string>('');\n\n /** Smaller label under the value. */\n readonly centerLabel = input<string>('');\n\n // Drawn in a 100×100 viewBox.\n private readonly outerR = 50;\n\n protected readonly innerR = computed(() => {\n const thickness = this.thickness();\n // 0 = solid pie: fill all the way to the center, not a zero-width ring.\n if (thickness === 0) return 0;\n return this.outerR * (1 - thickness / 100);\n });\n\n protected readonly total = computed(() => {\n const sum = this.segments().reduce((acc, s) => acc + Math.max(0, s.value), 0);\n return sum > 0 ? sum : 1;\n });\n\n /** Resolved slices ready for the template — each carries its arc path. */\n protected readonly slices = computed(() => {\n const total = this.total();\n let cumulative = 0;\n return this.segments().map((s, i) => {\n const value = Math.max(0, s.value);\n const startAngle = (cumulative / total) * Math.PI * 2;\n cumulative += value;\n const endAngle = (cumulative / total) * Math.PI * 2;\n return {\n label: s.label,\n value,\n color: s.color ?? FALLBACK_COLORS[i % FALLBACK_COLORS.length],\n path: this.arcPath(startAngle, endAngle),\n percent: (value / total) * 100,\n };\n });\n });\n\n // Helpers\n\n /** SVG path for one donut slice using outer and inner arcs. */\n private arcPath(start: number, end: number): string {\n const cx = 50;\n const cy = 50;\n const ro = this.outerR;\n const ri = this.innerR();\n const sweep = end - start;\n if (sweep <= 0) return '';\n // Full-circle slice — two halves so the arc can render.\n if (sweep >= Math.PI * 2 - 1e-6) {\n const path = [\n `M ${cx + ro} ${cy}`,\n `A ${ro} ${ro} 0 1 1 ${cx - ro} ${cy}`,\n `A ${ro} ${ro} 0 1 1 ${cx + ro} ${cy}`,\n ];\n if (ri > 0) {\n path.push(`M ${cx + ri} ${cy}`, `A ${ri} ${ri} 0 1 0 ${cx - ri} ${cy}`, `A ${ri} ${ri} 0 1 0 ${cx + ri} ${cy}`);\n }\n return path.join(' ');\n }\n const largeArc = sweep > Math.PI ? 1 : 0;\n const sox = cx + ro * Math.cos(start);\n const soy = cy + ro * Math.sin(start);\n const eox = cx + ro * Math.cos(end);\n const eoy = cy + ro * Math.sin(end);\n if (ri === 0) {\n return `M ${cx} ${cy} L ${sox.toFixed(2)} ${soy.toFixed(2)} A ${ro} ${ro} 0 ${largeArc} 1 ${eox.toFixed(2)} ${eoy.toFixed(2)} Z`;\n }\n const eix = cx + ri * Math.cos(end);\n const eiy = cy + ri * Math.sin(end);\n const six = cx + ri * Math.cos(start);\n const siy = cy + ri * Math.sin(start);\n return [\n `M ${sox.toFixed(2)} ${soy.toFixed(2)}`,\n `A ${ro} ${ro} 0 ${largeArc} 1 ${eox.toFixed(2)} ${eoy.toFixed(2)}`,\n `L ${eix.toFixed(2)} ${eiy.toFixed(2)}`,\n `A ${ri} ${ri} 0 ${largeArc} 0 ${six.toFixed(2)} ${siy.toFixed(2)}`,\n 'Z',\n ].join(' ');\n }\n}\n\nexport type { WrDonutSegment } from './interfaces';\n","<div class=\"wr-donut-chart__surface\" [style.width.px]=\"size()\">\n <svg viewBox=\"0 0 100 100\" aria-hidden=\"true\">\n @for (slice of slices(); track $index) {\n <path [attr.d]=\"slice.path\" [attr.fill]=\"slice.color\" />\n }\n </svg>\n @if (centerValue() || centerLabel()) {\n <div class=\"wr-donut-chart__center\">\n @if (centerValue()) {\n <div class=\"wr-donut-chart__center-value\">{{ centerValue() }}</div>\n }\n @if (centerLabel()) {\n <div class=\"wr-donut-chart__center-label\">{{ centerLabel() }}</div>\n }\n </div>\n }\n</div>\n\n@if (showLegend()) {\n <ul class=\"wr-donut-chart__legend\">\n @for (slice of slices(); track $index) {\n <li class=\"wr-donut-chart__legend-item\">\n <span class=\"wr-donut-chart__swatch\" [style.background]=\"slice.color\"></span>\n <span class=\"wr-donut-chart__legend-label\">{{ slice.label }}</span>\n <span class=\"wr-donut-chart__legend-value\">{{ slice.value }}</span>\n </li>\n }\n </ul>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngwr-donut-chart.mjs","sources":["../../../projects/lib/donut-chart/donut-chart.ts","../../../projects/lib/donut-chart/donut-chart.html","../../../projects/lib/donut-chart/ngwr-donut-chart.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';\nimport { Component, ViewEncapsulation, computed, input } from '@angular/core';\n\nimport { useI18nText } from 'ngwr/i18n';\n\nimport type { WrDonutSegment } from './interfaces';\n\n/**\n * A segment's contribution to the ring. `Math.max(0, NaN)` is NaN, and the running total\n * carries it forward — so one non-finite datum used to take out its own arc AND every arc\n * after it, writing the literal text `NaN` into the path `d`.\n */\nfunction weight(value: number): number {\n return Number.isFinite(value) ? Math.max(0, value) : 0;\n}\n\nconst FALLBACK_COLORS = [\n 'var(--wr-color-primary)',\n 'var(--wr-color-secondary)',\n 'var(--wr-color-success)',\n 'var(--wr-color-warning)',\n 'var(--wr-color-danger)',\n 'var(--wr-color-medium)',\n];\n\n/**\n * Donut chart. Set `thickness` to 0 for a solid pie. Optional center\n * text via inputs.\n *\n * @example\n * ```html\n * <wr-donut-chart [segments]=\"[\n * { label: 'Used', value: 60 },\n * { label: 'Free', value: 40 }\n * ]\" centerLabel=\"Disk\" centerValue=\"60%\" />\n * ```\n *\n * @see https://ngwr.dev/reference/components/donut-chart\n */\n@Component({\n selector: 'wr-donut-chart',\n templateUrl: './donut-chart.html',\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-donut-chart' },\n})\nexport class WrDonutChart {\n readonly segments = input<readonly WrDonutSegment[]>([]);\n\n /**\n * Accessible name of the chart. The ring is `aria-hidden` and the legend is optional,\n * so with `showLegend: false` this is the only thing a screen reader gets. Falls back\n * to `donutChart.label`.\n */\n readonly ariaLabel = input<string | null>(null);\n\n protected readonly resolvedAriaLabel = useI18nText(this.ariaLabel, 'donutChart.label', 'Donut chart');\n\n /** Diameter in CSS pixels. @default 200 */\n readonly size = input(200, { transform: (v: unknown): number => Math.max(48, coerceNumberProperty(v, 200)) });\n\n /** Inner-ring thickness as a percent of radius (0–100). `0` = solid pie. @default 30 */\n readonly thickness = input(30, {\n transform: (v: unknown): number => Math.min(100, Math.max(0, coerceNumberProperty(v, 30))),\n });\n\n /** Show the legend under the chart. @default true */\n readonly showLegend = input(true, { transform: coerceBooleanProperty });\n\n /** Bold value text in the center. */\n readonly centerValue = input<string>('');\n\n /** Smaller label under the value. */\n readonly centerLabel = input<string>('');\n\n // Drawn in a 100×100 viewBox.\n private readonly outerR = 50;\n\n protected readonly innerR = computed(() => {\n const thickness = this.thickness();\n // 0 = solid pie: fill all the way to the center, not a zero-width ring.\n if (thickness === 0) return 0;\n return this.outerR * (1 - thickness / 100);\n });\n\n protected readonly total = computed(() => {\n const sum = this.segments().reduce((acc, s) => acc + weight(s.value), 0);\n return sum > 0 ? sum : 1;\n });\n\n /** Resolved slices ready for the template — each carries its arc path. */\n protected readonly slices = computed(() => {\n const total = this.total();\n let cumulative = 0;\n return this.segments().map((s, i) => {\n const value = weight(s.value);\n const startAngle = (cumulative / total) * Math.PI * 2;\n cumulative += value;\n const endAngle = (cumulative / total) * Math.PI * 2;\n return {\n label: s.label,\n value,\n color: s.color ?? FALLBACK_COLORS[i % FALLBACK_COLORS.length],\n path: this.arcPath(startAngle, endAngle),\n percent: (value / total) * 100,\n };\n });\n });\n\n // Helpers\n\n /** SVG path for one donut slice using outer and inner arcs. */\n private arcPath(start: number, end: number): string {\n const cx = 50;\n const cy = 50;\n const ro = this.outerR;\n const ri = this.innerR();\n const sweep = end - start;\n if (sweep <= 0) return '';\n // Full-circle slice — two halves so the arc can render.\n if (sweep >= Math.PI * 2 - 1e-6) {\n const path = [\n `M ${cx + ro} ${cy}`,\n `A ${ro} ${ro} 0 1 1 ${cx - ro} ${cy}`,\n `A ${ro} ${ro} 0 1 1 ${cx + ro} ${cy}`,\n ];\n if (ri > 0) {\n path.push(`M ${cx + ri} ${cy}`, `A ${ri} ${ri} 0 1 0 ${cx - ri} ${cy}`, `A ${ri} ${ri} 0 1 0 ${cx + ri} ${cy}`);\n }\n return path.join(' ');\n }\n const largeArc = sweep > Math.PI ? 1 : 0;\n const sox = cx + ro * Math.cos(start);\n const soy = cy + ro * Math.sin(start);\n const eox = cx + ro * Math.cos(end);\n const eoy = cy + ro * Math.sin(end);\n if (ri === 0) {\n return `M ${cx} ${cy} L ${sox.toFixed(2)} ${soy.toFixed(2)} A ${ro} ${ro} 0 ${largeArc} 1 ${eox.toFixed(2)} ${eoy.toFixed(2)} Z`;\n }\n const eix = cx + ri * Math.cos(end);\n const eiy = cy + ri * Math.sin(end);\n const six = cx + ri * Math.cos(start);\n const siy = cy + ri * Math.sin(start);\n return [\n `M ${sox.toFixed(2)} ${soy.toFixed(2)}`,\n `A ${ro} ${ro} 0 ${largeArc} 1 ${eox.toFixed(2)} ${eoy.toFixed(2)}`,\n `L ${eix.toFixed(2)} ${eiy.toFixed(2)}`,\n `A ${ri} ${ri} 0 ${largeArc} 0 ${six.toFixed(2)} ${siy.toFixed(2)}`,\n 'Z',\n ].join(' ');\n }\n}\n\nexport type { WrDonutSegment } from './interfaces';\n","<div class=\"wr-donut-chart__surface\" role=\"img\" [attr.aria-label]=\"resolvedAriaLabel()\" [style.width.px]=\"size()\">\n <svg viewBox=\"0 0 100 100\" aria-hidden=\"true\">\n @for (slice of slices(); track $index) {\n <path [attr.d]=\"slice.path\" [attr.fill]=\"slice.color\" />\n }\n </svg>\n @if (centerValue() || centerLabel()) {\n <div class=\"wr-donut-chart__center\">\n @if (centerValue()) {\n <div class=\"wr-donut-chart__center-value\">{{ centerValue() }}</div>\n }\n @if (centerLabel()) {\n <div class=\"wr-donut-chart__center-label\">{{ centerLabel() }}</div>\n }\n </div>\n }\n</div>\n\n@if (showLegend() && slices().length > 0) {\n <ul class=\"wr-donut-chart__legend\">\n @for (slice of slices(); track $index) {\n <li class=\"wr-donut-chart__legend-item\">\n <span class=\"wr-donut-chart__swatch\" [style.background]=\"slice.color\"></span>\n <span class=\"wr-donut-chart__legend-label\">{{ slice.label }}</span>\n <span class=\"wr-donut-chart__legend-value\">{{ slice.value }}</span>\n </li>\n }\n </ul>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}