ngwr 14.8.0 → 14.9.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 (447) hide show
  1. package/README.md +66 -332
  2. package/alert/styles/_index.scss +10 -0
  3. package/avatar/styles/_index.scss +18 -7
  4. package/badge/styles/_index.scss +7 -0
  5. package/badge/styles/_tag.scss +7 -1
  6. package/button/styles/_index.scss +6 -0
  7. package/cascader/styles/_rules.scss +1 -1
  8. package/checkbox/styles/_index.scss +4 -0
  9. package/command-palette/styles/_index.scss +1 -1
  10. package/divider/styles/_index.scss +2 -0
  11. package/editor/styles/_index.scss +441 -0
  12. package/fesm2022/ngwr-action-sheet-testing.mjs.map +1 -1
  13. package/fesm2022/ngwr-action-sheet.mjs +3 -3
  14. package/fesm2022/ngwr-action-sheet.mjs.map +1 -1
  15. package/fesm2022/ngwr-affix.mjs +3 -3
  16. package/fesm2022/ngwr-affix.mjs.map +1 -1
  17. package/fesm2022/ngwr-alert.mjs +3 -3
  18. package/fesm2022/ngwr-alert.mjs.map +1 -1
  19. package/fesm2022/ngwr-anchor.mjs +3 -3
  20. package/fesm2022/ngwr-anchor.mjs.map +1 -1
  21. package/fesm2022/ngwr-aurora.mjs +3 -3
  22. package/fesm2022/ngwr-aurora.mjs.map +1 -1
  23. package/fesm2022/ngwr-avatar.mjs +3 -3
  24. package/fesm2022/ngwr-avatar.mjs.map +1 -1
  25. package/fesm2022/ngwr-back-top.mjs +3 -3
  26. package/fesm2022/ngwr-back-top.mjs.map +1 -1
  27. package/fesm2022/ngwr-badge.mjs +28 -13
  28. package/fesm2022/ngwr-badge.mjs.map +1 -1
  29. package/fesm2022/ngwr-bar-chart-testing.mjs.map +1 -1
  30. package/fesm2022/ngwr-bar-chart.mjs +3 -3
  31. package/fesm2022/ngwr-bar-chart.mjs.map +1 -1
  32. package/fesm2022/ngwr-blur-text-testing.mjs.map +1 -1
  33. package/fesm2022/ngwr-blur-text.mjs +3 -3
  34. package/fesm2022/ngwr-blur-text.mjs.map +1 -1
  35. package/fesm2022/ngwr-border-glow-testing.mjs.map +1 -1
  36. package/fesm2022/ngwr-border-glow.mjs +3 -3
  37. package/fesm2022/ngwr-border-glow.mjs.map +1 -1
  38. package/fesm2022/ngwr-breadcrumbs.mjs +6 -6
  39. package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
  40. package/fesm2022/ngwr-burger.mjs +3 -3
  41. package/fesm2022/ngwr-burger.mjs.map +1 -1
  42. package/fesm2022/ngwr-button-testing.mjs.map +1 -1
  43. package/fesm2022/ngwr-button.mjs +6 -6
  44. package/fesm2022/ngwr-button.mjs.map +1 -1
  45. package/fesm2022/ngwr-calendar-heatmap-testing.mjs.map +1 -1
  46. package/fesm2022/ngwr-calendar-heatmap.mjs +3 -3
  47. package/fesm2022/ngwr-calendar-heatmap.mjs.map +1 -1
  48. package/fesm2022/ngwr-calendar-testing.mjs.map +1 -1
  49. package/fesm2022/ngwr-calendar.mjs +3 -3
  50. package/fesm2022/ngwr-calendar.mjs.map +1 -1
  51. package/fesm2022/ngwr-card.mjs +9 -9
  52. package/fesm2022/ngwr-card.mjs.map +1 -1
  53. package/fesm2022/ngwr-carousel-testing.mjs.map +1 -1
  54. package/fesm2022/ngwr-carousel.mjs +6 -6
  55. package/fesm2022/ngwr-carousel.mjs.map +1 -1
  56. package/fesm2022/ngwr-cascader-testing.mjs.map +1 -1
  57. package/fesm2022/ngwr-cascader.mjs +4 -4
  58. package/fesm2022/ngwr-cascader.mjs.map +1 -1
  59. package/fesm2022/ngwr-checkbox-testing.mjs.map +1 -1
  60. package/fesm2022/ngwr-checkbox.mjs +6 -6
  61. package/fesm2022/ngwr-checkbox.mjs.map +1 -1
  62. package/fesm2022/ngwr-circular-text-testing.mjs.map +1 -1
  63. package/fesm2022/ngwr-circular-text.mjs +3 -3
  64. package/fesm2022/ngwr-circular-text.mjs.map +1 -1
  65. package/fesm2022/ngwr-click-spark.mjs +3 -3
  66. package/fesm2022/ngwr-click-spark.mjs.map +1 -1
  67. package/fesm2022/ngwr-clipboard.mjs +3 -3
  68. package/fesm2022/ngwr-clipboard.mjs.map +1 -1
  69. package/fesm2022/ngwr-collapse-testing.mjs.map +1 -1
  70. package/fesm2022/ngwr-collapse.mjs +9 -9
  71. package/fesm2022/ngwr-collapse.mjs.map +1 -1
  72. package/fesm2022/ngwr-color-picker-testing.mjs.map +1 -1
  73. package/fesm2022/ngwr-color-picker.mjs +6 -6
  74. package/fesm2022/ngwr-color-picker.mjs.map +1 -1
  75. package/fesm2022/ngwr-command-palette-testing.mjs.map +1 -1
  76. package/fesm2022/ngwr-command-palette.mjs +3 -3
  77. package/fesm2022/ngwr-command-palette.mjs.map +1 -1
  78. package/fesm2022/ngwr-compare.mjs +3 -3
  79. package/fesm2022/ngwr-compare.mjs.map +1 -1
  80. package/fesm2022/ngwr-confetti.mjs +3 -3
  81. package/fesm2022/ngwr-confetti.mjs.map +1 -1
  82. package/fesm2022/ngwr-config.mjs.map +1 -1
  83. package/fesm2022/ngwr-context-menu-testing.mjs.map +1 -1
  84. package/fesm2022/ngwr-context-menu.mjs +12 -12
  85. package/fesm2022/ngwr-context-menu.mjs.map +1 -1
  86. package/fesm2022/ngwr-cookie.mjs +3 -3
  87. package/fesm2022/ngwr-cookie.mjs.map +1 -1
  88. package/fesm2022/ngwr-counter.mjs +6 -6
  89. package/fesm2022/ngwr-counter.mjs.map +1 -1
  90. package/fesm2022/ngwr-date-adapters-fns.mjs +3 -3
  91. package/fesm2022/ngwr-date-adapters-fns.mjs.map +1 -1
  92. package/fesm2022/ngwr-date-adapters-luxon.mjs +3 -3
  93. package/fesm2022/ngwr-date-adapters-luxon.mjs.map +1 -1
  94. package/fesm2022/ngwr-date-picker-testing.mjs.map +1 -1
  95. package/fesm2022/ngwr-date-picker.mjs +21 -21
  96. package/fesm2022/ngwr-date-picker.mjs.map +1 -1
  97. package/fesm2022/ngwr-date.mjs +3 -3
  98. package/fesm2022/ngwr-date.mjs.map +1 -1
  99. package/fesm2022/ngwr-decrypt-text-testing.mjs.map +1 -1
  100. package/fesm2022/ngwr-decrypt-text.mjs +3 -3
  101. package/fesm2022/ngwr-decrypt-text.mjs.map +1 -1
  102. package/fesm2022/ngwr-density.mjs +6 -6
  103. package/fesm2022/ngwr-density.mjs.map +1 -1
  104. package/fesm2022/ngwr-descriptions.mjs +6 -6
  105. package/fesm2022/ngwr-descriptions.mjs.map +1 -1
  106. package/fesm2022/ngwr-dialog-testing.mjs.map +1 -1
  107. package/fesm2022/ngwr-dialog.mjs +15 -15
  108. package/fesm2022/ngwr-dialog.mjs.map +1 -1
  109. package/fesm2022/ngwr-directives.mjs +12 -12
  110. package/fesm2022/ngwr-directives.mjs.map +1 -1
  111. package/fesm2022/ngwr-divider.mjs +3 -3
  112. package/fesm2022/ngwr-divider.mjs.map +1 -1
  113. package/fesm2022/ngwr-donut-chart-testing.mjs.map +1 -1
  114. package/fesm2022/ngwr-donut-chart.mjs +3 -3
  115. package/fesm2022/ngwr-donut-chart.mjs.map +1 -1
  116. package/fesm2022/ngwr-drag-drop.mjs +6 -6
  117. package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
  118. package/fesm2022/ngwr-drawer-testing.mjs.map +1 -1
  119. package/fesm2022/ngwr-drawer.mjs +18 -18
  120. package/fesm2022/ngwr-drawer.mjs.map +1 -1
  121. package/fesm2022/ngwr-dropdown-testing.mjs.map +1 -1
  122. package/fesm2022/ngwr-dropdown.mjs +9 -9
  123. package/fesm2022/ngwr-dropdown.mjs.map +1 -1
  124. package/fesm2022/ngwr-editor-testing.mjs +568 -0
  125. package/fesm2022/ngwr-editor-testing.mjs.map +1 -0
  126. package/fesm2022/ngwr-editor.mjs +2601 -0
  127. package/fesm2022/ngwr-editor.mjs.map +1 -0
  128. package/fesm2022/ngwr-empty.mjs +3 -3
  129. package/fesm2022/ngwr-empty.mjs.map +1 -1
  130. package/fesm2022/ngwr-event-calendar-testing.mjs.map +1 -1
  131. package/fesm2022/ngwr-event-calendar.mjs +6 -6
  132. package/fesm2022/ngwr-event-calendar.mjs.map +1 -1
  133. package/fesm2022/ngwr-falling-text-testing.mjs.map +1 -1
  134. package/fesm2022/ngwr-falling-text.mjs +3 -3
  135. package/fesm2022/ngwr-falling-text.mjs.map +1 -1
  136. package/fesm2022/ngwr-file-upload-testing.mjs.map +1 -1
  137. package/fesm2022/ngwr-file-upload.mjs +3 -3
  138. package/fesm2022/ngwr-file-upload.mjs.map +1 -1
  139. package/fesm2022/ngwr-form-testing.mjs.map +1 -1
  140. package/fesm2022/ngwr-form.mjs +9 -9
  141. package/fesm2022/ngwr-form.mjs.map +1 -1
  142. package/fesm2022/ngwr-fuzzy-text-testing.mjs.map +1 -1
  143. package/fesm2022/ngwr-fuzzy-text.mjs +3 -3
  144. package/fesm2022/ngwr-fuzzy-text.mjs.map +1 -1
  145. package/fesm2022/ngwr-gauge-testing.mjs.map +1 -1
  146. package/fesm2022/ngwr-gauge.mjs +3 -3
  147. package/fesm2022/ngwr-gauge.mjs.map +1 -1
  148. package/fesm2022/ngwr-glitch-text-testing.mjs.map +1 -1
  149. package/fesm2022/ngwr-glitch-text.mjs +3 -3
  150. package/fesm2022/ngwr-glitch-text.mjs.map +1 -1
  151. package/fesm2022/ngwr-gradient-text-testing.mjs.map +1 -1
  152. package/fesm2022/ngwr-gradient-text.mjs +3 -3
  153. package/fesm2022/ngwr-gradient-text.mjs.map +1 -1
  154. package/fesm2022/ngwr-graph-testing.mjs.map +1 -1
  155. package/fesm2022/ngwr-graph.mjs +6 -6
  156. package/fesm2022/ngwr-graph.mjs.map +1 -1
  157. package/fesm2022/ngwr-hotkey.mjs +6 -6
  158. package/fesm2022/ngwr-hotkey.mjs.map +1 -1
  159. package/fesm2022/ngwr-i18n-ar.mjs +29 -0
  160. package/fesm2022/ngwr-i18n-ar.mjs.map +1 -1
  161. package/fesm2022/ngwr-i18n-cs.mjs +29 -0
  162. package/fesm2022/ngwr-i18n-cs.mjs.map +1 -1
  163. package/fesm2022/ngwr-i18n-de.mjs +29 -0
  164. package/fesm2022/ngwr-i18n-de.mjs.map +1 -1
  165. package/fesm2022/ngwr-i18n-en.mjs +34 -0
  166. package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
  167. package/fesm2022/ngwr-i18n-es.mjs +29 -0
  168. package/fesm2022/ngwr-i18n-es.mjs.map +1 -1
  169. package/fesm2022/ngwr-i18n-fr.mjs +29 -0
  170. package/fesm2022/ngwr-i18n-fr.mjs.map +1 -1
  171. package/fesm2022/ngwr-i18n-he.mjs +29 -0
  172. package/fesm2022/ngwr-i18n-he.mjs.map +1 -1
  173. package/fesm2022/ngwr-i18n-hi.mjs +29 -0
  174. package/fesm2022/ngwr-i18n-hi.mjs.map +1 -1
  175. package/fesm2022/ngwr-i18n-id.mjs +29 -0
  176. package/fesm2022/ngwr-i18n-id.mjs.map +1 -1
  177. package/fesm2022/ngwr-i18n-it.mjs +29 -0
  178. package/fesm2022/ngwr-i18n-it.mjs.map +1 -1
  179. package/fesm2022/ngwr-i18n-ja.mjs +29 -0
  180. package/fesm2022/ngwr-i18n-ja.mjs.map +1 -1
  181. package/fesm2022/ngwr-i18n-ko.mjs +29 -0
  182. package/fesm2022/ngwr-i18n-ko.mjs.map +1 -1
  183. package/fesm2022/ngwr-i18n-nl.mjs +29 -0
  184. package/fesm2022/ngwr-i18n-nl.mjs.map +1 -1
  185. package/fesm2022/ngwr-i18n-pl.mjs +29 -0
  186. package/fesm2022/ngwr-i18n-pl.mjs.map +1 -1
  187. package/fesm2022/ngwr-i18n-pt.mjs +29 -0
  188. package/fesm2022/ngwr-i18n-pt.mjs.map +1 -1
  189. package/fesm2022/ngwr-i18n-ru.mjs +29 -0
  190. package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
  191. package/fesm2022/ngwr-i18n-sv.mjs +29 -0
  192. package/fesm2022/ngwr-i18n-sv.mjs.map +1 -1
  193. package/fesm2022/ngwr-i18n-tr.mjs +29 -0
  194. package/fesm2022/ngwr-i18n-tr.mjs.map +1 -1
  195. package/fesm2022/ngwr-i18n-uk.mjs +29 -0
  196. package/fesm2022/ngwr-i18n-uk.mjs.map +1 -1
  197. package/fesm2022/ngwr-i18n-vi.mjs +29 -0
  198. package/fesm2022/ngwr-i18n-vi.mjs.map +1 -1
  199. package/fesm2022/ngwr-i18n-zh-TW.mjs +29 -0
  200. package/fesm2022/ngwr-i18n-zh-TW.mjs.map +1 -1
  201. package/fesm2022/ngwr-i18n-zh.mjs +29 -0
  202. package/fesm2022/ngwr-i18n-zh.mjs.map +1 -1
  203. package/fesm2022/ngwr-i18n.mjs +9 -9
  204. package/fesm2022/ngwr-i18n.mjs.map +1 -1
  205. package/fesm2022/ngwr-icon-adapters-feather.mjs.map +1 -1
  206. package/fesm2022/ngwr-icon-adapters-lucide.mjs.map +1 -1
  207. package/fesm2022/ngwr-icon.mjs +6 -6
  208. package/fesm2022/ngwr-icon.mjs.map +1 -1
  209. package/fesm2022/ngwr-image-cropper-testing.mjs.map +1 -1
  210. package/fesm2022/ngwr-image-cropper.mjs +3 -3
  211. package/fesm2022/ngwr-image-cropper.mjs.map +1 -1
  212. package/fesm2022/ngwr-input-number-testing.mjs.map +1 -1
  213. package/fesm2022/ngwr-input-number.mjs +3 -3
  214. package/fesm2022/ngwr-input-number.mjs.map +1 -1
  215. package/fesm2022/ngwr-input-otp-testing.mjs.map +1 -1
  216. package/fesm2022/ngwr-input-otp.mjs +3 -3
  217. package/fesm2022/ngwr-input-otp.mjs.map +1 -1
  218. package/fesm2022/ngwr-input-testing.mjs.map +1 -1
  219. package/fesm2022/ngwr-input.mjs +15 -15
  220. package/fesm2022/ngwr-input.mjs.map +1 -1
  221. package/fesm2022/ngwr-keyboard.mjs +3 -3
  222. package/fesm2022/ngwr-keyboard.mjs.map +1 -1
  223. package/fesm2022/ngwr-knob-testing.mjs.map +1 -1
  224. package/fesm2022/ngwr-knob.mjs +3 -3
  225. package/fesm2022/ngwr-knob.mjs.map +1 -1
  226. package/fesm2022/ngwr-layout.mjs +15 -15
  227. package/fesm2022/ngwr-layout.mjs.map +1 -1
  228. package/fesm2022/ngwr-lightbox-testing.mjs.map +1 -1
  229. package/fesm2022/ngwr-lightbox.mjs +3 -3
  230. package/fesm2022/ngwr-lightbox.mjs.map +1 -1
  231. package/fesm2022/ngwr-line-chart-testing.mjs.map +1 -1
  232. package/fesm2022/ngwr-line-chart.mjs +3 -3
  233. package/fesm2022/ngwr-line-chart.mjs.map +1 -1
  234. package/fesm2022/ngwr-list.mjs +6 -6
  235. package/fesm2022/ngwr-list.mjs.map +1 -1
  236. package/fesm2022/ngwr-loading-bar-router.mjs.map +1 -1
  237. package/fesm2022/ngwr-loading-bar.mjs +6 -6
  238. package/fesm2022/ngwr-loading-bar.mjs.map +1 -1
  239. package/fesm2022/ngwr-markdown-testing.mjs.map +1 -1
  240. package/fesm2022/ngwr-markdown.mjs +798 -17
  241. package/fesm2022/ngwr-markdown.mjs.map +1 -1
  242. package/fesm2022/ngwr-marquee-testing.mjs.map +1 -1
  243. package/fesm2022/ngwr-marquee.mjs +3 -3
  244. package/fesm2022/ngwr-marquee.mjs.map +1 -1
  245. package/fesm2022/ngwr-media.mjs +3 -3
  246. package/fesm2022/ngwr-media.mjs.map +1 -1
  247. package/fesm2022/ngwr-mention-testing.mjs.map +1 -1
  248. package/fesm2022/ngwr-mention.mjs +6 -6
  249. package/fesm2022/ngwr-mention.mjs.map +1 -1
  250. package/fesm2022/ngwr-meta.mjs +6 -6
  251. package/fesm2022/ngwr-meta.mjs.map +1 -1
  252. package/fesm2022/ngwr-meter-group-testing.mjs.map +1 -1
  253. package/fesm2022/ngwr-meter-group.mjs +3 -3
  254. package/fesm2022/ngwr-meter-group.mjs.map +1 -1
  255. package/fesm2022/ngwr-overlay.mjs +6 -6
  256. package/fesm2022/ngwr-overlay.mjs.map +1 -1
  257. package/fesm2022/ngwr-page-header.mjs +3 -3
  258. package/fesm2022/ngwr-page-header.mjs.map +1 -1
  259. package/fesm2022/ngwr-pagination-testing.mjs.map +1 -1
  260. package/fesm2022/ngwr-pagination.mjs +3 -3
  261. package/fesm2022/ngwr-pagination.mjs.map +1 -1
  262. package/fesm2022/ngwr-pipes.mjs +21 -21
  263. package/fesm2022/ngwr-pipes.mjs.map +1 -1
  264. package/fesm2022/ngwr-platform.mjs +9 -9
  265. package/fesm2022/ngwr-platform.mjs.map +1 -1
  266. package/fesm2022/ngwr-popconfirm-testing.mjs.map +1 -1
  267. package/fesm2022/ngwr-popconfirm.mjs +6 -6
  268. package/fesm2022/ngwr-popconfirm.mjs.map +1 -1
  269. package/fesm2022/ngwr-popover-testing.mjs.map +1 -1
  270. package/fesm2022/ngwr-popover.mjs +12 -12
  271. package/fesm2022/ngwr-popover.mjs.map +1 -1
  272. package/fesm2022/ngwr-progress.mjs +3 -3
  273. package/fesm2022/ngwr-progress.mjs.map +1 -1
  274. package/fesm2022/ngwr-pull-to-refresh.mjs +3 -3
  275. package/fesm2022/ngwr-pull-to-refresh.mjs.map +1 -1
  276. package/fesm2022/ngwr-qr.mjs +3 -3
  277. package/fesm2022/ngwr-qr.mjs.map +1 -1
  278. package/fesm2022/ngwr-radio-testing.mjs.map +1 -1
  279. package/fesm2022/ngwr-radio.mjs +6 -6
  280. package/fesm2022/ngwr-radio.mjs.map +1 -1
  281. package/fesm2022/ngwr-rating-testing.mjs.map +1 -1
  282. package/fesm2022/ngwr-rating.mjs +3 -3
  283. package/fesm2022/ngwr-rating.mjs.map +1 -1
  284. package/fesm2022/ngwr-result.mjs +12 -12
  285. package/fesm2022/ngwr-result.mjs.map +1 -1
  286. package/fesm2022/ngwr-rotating-text-testing.mjs.map +1 -1
  287. package/fesm2022/ngwr-rotating-text.mjs +3 -3
  288. package/fesm2022/ngwr-rotating-text.mjs.map +1 -1
  289. package/fesm2022/ngwr-schema-form.mjs +3 -3
  290. package/fesm2022/ngwr-schema-form.mjs.map +1 -1
  291. package/fesm2022/ngwr-scroll.mjs +3 -3
  292. package/fesm2022/ngwr-scroll.mjs.map +1 -1
  293. package/fesm2022/ngwr-segmented-testing.mjs.map +1 -1
  294. package/fesm2022/ngwr-segmented.mjs +3 -3
  295. package/fesm2022/ngwr-segmented.mjs.map +1 -1
  296. package/fesm2022/ngwr-select-testing.mjs.map +1 -1
  297. package/fesm2022/ngwr-select.mjs +12 -12
  298. package/fesm2022/ngwr-select.mjs.map +1 -1
  299. package/fesm2022/ngwr-shiny-text-testing.mjs.map +1 -1
  300. package/fesm2022/ngwr-shiny-text.mjs +6 -6
  301. package/fesm2022/ngwr-shiny-text.mjs.map +1 -1
  302. package/fesm2022/ngwr-sidebar.mjs +3 -3
  303. package/fesm2022/ngwr-sidebar.mjs.map +1 -1
  304. package/fesm2022/ngwr-skeleton.mjs +3 -3
  305. package/fesm2022/ngwr-skeleton.mjs.map +1 -1
  306. package/fesm2022/ngwr-slider-testing.mjs.map +1 -1
  307. package/fesm2022/ngwr-slider.mjs +3 -3
  308. package/fesm2022/ngwr-slider.mjs.map +1 -1
  309. package/fesm2022/ngwr-sparkline-testing.mjs.map +1 -1
  310. package/fesm2022/ngwr-sparkline.mjs +3 -3
  311. package/fesm2022/ngwr-sparkline.mjs.map +1 -1
  312. package/fesm2022/ngwr-speed-dial-testing.mjs.map +1 -1
  313. package/fesm2022/ngwr-speed-dial.mjs +3 -3
  314. package/fesm2022/ngwr-speed-dial.mjs.map +1 -1
  315. package/fesm2022/ngwr-spinner.mjs +3 -3
  316. package/fesm2022/ngwr-spinner.mjs.map +1 -1
  317. package/fesm2022/ngwr-splash-cursor-testing.mjs.map +1 -1
  318. package/fesm2022/ngwr-splash-cursor.mjs +3 -3
  319. package/fesm2022/ngwr-splash-cursor.mjs.map +1 -1
  320. package/fesm2022/ngwr-split-text-testing.mjs.map +1 -1
  321. package/fesm2022/ngwr-split-text.mjs +3 -3
  322. package/fesm2022/ngwr-split-text.mjs.map +1 -1
  323. package/fesm2022/ngwr-splitter-testing.mjs.map +1 -1
  324. package/fesm2022/ngwr-splitter.mjs +3 -3
  325. package/fesm2022/ngwr-splitter.mjs.map +1 -1
  326. package/fesm2022/ngwr-spotlight-card-testing.mjs.map +1 -1
  327. package/fesm2022/ngwr-spotlight-card.mjs +6 -6
  328. package/fesm2022/ngwr-spotlight-card.mjs.map +1 -1
  329. package/fesm2022/ngwr-squircle.mjs +6 -6
  330. package/fesm2022/ngwr-squircle.mjs.map +1 -1
  331. package/fesm2022/ngwr-star-border-testing.mjs.map +1 -1
  332. package/fesm2022/ngwr-star-border.mjs +3 -3
  333. package/fesm2022/ngwr-star-border.mjs.map +1 -1
  334. package/fesm2022/ngwr-statistic.mjs +9 -9
  335. package/fesm2022/ngwr-statistic.mjs.map +1 -1
  336. package/fesm2022/ngwr-stepper-testing.mjs.map +1 -1
  337. package/fesm2022/ngwr-stepper.mjs +6 -6
  338. package/fesm2022/ngwr-stepper.mjs.map +1 -1
  339. package/fesm2022/ngwr-storage.mjs +3 -3
  340. package/fesm2022/ngwr-storage.mjs.map +1 -1
  341. package/fesm2022/ngwr-switch-testing.mjs.map +1 -1
  342. package/fesm2022/ngwr-switch.mjs +3 -3
  343. package/fesm2022/ngwr-switch.mjs.map +1 -1
  344. package/fesm2022/ngwr-table-testing.mjs.map +1 -1
  345. package/fesm2022/ngwr-table.mjs +18 -18
  346. package/fesm2022/ngwr-table.mjs.map +1 -1
  347. package/fesm2022/ngwr-tabs-router.mjs +3 -3
  348. package/fesm2022/ngwr-tabs-router.mjs.map +1 -1
  349. package/fesm2022/ngwr-tabs-testing.mjs.map +1 -1
  350. package/fesm2022/ngwr-tabs.mjs +6 -6
  351. package/fesm2022/ngwr-tabs.mjs.map +1 -1
  352. package/fesm2022/ngwr-textarea-testing.mjs.map +1 -1
  353. package/fesm2022/ngwr-textarea.mjs +3 -3
  354. package/fesm2022/ngwr-textarea.mjs.map +1 -1
  355. package/fesm2022/ngwr-theme.mjs +3 -3
  356. package/fesm2022/ngwr-theme.mjs.map +1 -1
  357. package/fesm2022/ngwr-tilt-card-testing.mjs.map +1 -1
  358. package/fesm2022/ngwr-tilt-card.mjs +6 -6
  359. package/fesm2022/ngwr-tilt-card.mjs.map +1 -1
  360. package/fesm2022/ngwr-timeline.mjs +6 -6
  361. package/fesm2022/ngwr-timeline.mjs.map +1 -1
  362. package/fesm2022/ngwr-toast-testing.mjs.map +1 -1
  363. package/fesm2022/ngwr-toast.mjs +9 -9
  364. package/fesm2022/ngwr-toast.mjs.map +1 -1
  365. package/fesm2022/ngwr-toolbar.mjs +3 -3
  366. package/fesm2022/ngwr-toolbar.mjs.map +1 -1
  367. package/fesm2022/ngwr-tour-testing.mjs.map +1 -1
  368. package/fesm2022/ngwr-tour.mjs +6 -6
  369. package/fesm2022/ngwr-tour.mjs.map +1 -1
  370. package/fesm2022/ngwr-transfer-testing.mjs.map +1 -1
  371. package/fesm2022/ngwr-transfer.mjs +3 -3
  372. package/fesm2022/ngwr-transfer.mjs.map +1 -1
  373. package/fesm2022/ngwr-tree-testing.mjs.map +1 -1
  374. package/fesm2022/ngwr-tree.mjs +3 -3
  375. package/fesm2022/ngwr-tree.mjs.map +1 -1
  376. package/fesm2022/ngwr-typewriter-testing.mjs.map +1 -1
  377. package/fesm2022/ngwr-typewriter.mjs +3 -3
  378. package/fesm2022/ngwr-typewriter.mjs.map +1 -1
  379. package/fesm2022/ngwr-typography.mjs +7 -3
  380. package/fesm2022/ngwr-typography.mjs.map +1 -1
  381. package/fesm2022/ngwr-utils.mjs.map +1 -1
  382. package/fesm2022/ngwr-validators.mjs.map +1 -1
  383. package/fesm2022/ngwr-version.mjs +1 -1
  384. package/fesm2022/ngwr-version.mjs.map +1 -1
  385. package/fesm2022/ngwr-virtual-scroll.mjs +3 -3
  386. package/fesm2022/ngwr-virtual-scroll.mjs.map +1 -1
  387. package/fesm2022/ngwr-waves-testing.mjs.map +1 -1
  388. package/fesm2022/ngwr-waves.mjs +3 -3
  389. package/fesm2022/ngwr-waves.mjs.map +1 -1
  390. package/fesm2022/ngwr-window-testing.mjs.map +1 -1
  391. package/fesm2022/ngwr-window.mjs +12 -12
  392. package/fesm2022/ngwr-window.mjs.map +1 -1
  393. package/form/styles/_index.scss +5 -0
  394. package/i18n/ar.json +29 -0
  395. package/i18n/cs.json +29 -0
  396. package/i18n/de.json +29 -0
  397. package/i18n/en.json +29 -0
  398. package/i18n/es.json +29 -0
  399. package/i18n/fr.json +29 -0
  400. package/i18n/he.json +29 -0
  401. package/i18n/hi.json +29 -0
  402. package/i18n/id.json +29 -0
  403. package/i18n/it.json +29 -0
  404. package/i18n/ja.json +29 -0
  405. package/i18n/ko.json +29 -0
  406. package/i18n/nl.json +29 -0
  407. package/i18n/pl.json +29 -0
  408. package/i18n/pt.json +29 -0
  409. package/i18n/ru.json +29 -0
  410. package/i18n/sv.json +29 -0
  411. package/i18n/tr.json +29 -0
  412. package/i18n/uk.json +29 -0
  413. package/i18n/vi.json +29 -0
  414. package/i18n/zh-TW.json +29 -0
  415. package/i18n/zh.json +29 -0
  416. package/input/styles/_index.scss +5 -1
  417. package/input-otp/styles/_index.scss +5 -5
  418. package/llms-full.txt +11 -1
  419. package/llms.txt +188 -132
  420. package/mcp/providers.js +2 -2
  421. package/mcp/server.js +1 -1
  422. package/overlay/styles/_arrow.scss +3 -0
  423. package/package.json +43 -2
  424. package/progress/styles/_index.scss +4 -0
  425. package/radio/styles/_index.scss +4 -1
  426. package/schematics/use/symbol-map.json +1 -0
  427. package/select/styles/_index.scss +3 -3
  428. package/sidebar/styles/_index.scss +10 -0
  429. package/skeleton/styles/_index.scss +3 -0
  430. package/skills/ngwr/SKILL.md +5 -5
  431. package/skills/ngwr/references/catalog.md +2 -0
  432. package/skills/ngwr/references/setup.md +3 -3
  433. package/styles.scss +1 -0
  434. package/table/styles/_index.scss +7 -0
  435. package/textarea/styles/_index.scss +12 -3
  436. package/theme/styles/_colors.scss +39 -13
  437. package/theme/styles/_contrast.scss +9 -7
  438. package/toast/styles/_index.scss +4 -0
  439. package/tree/styles/_index.scss +1 -1
  440. package/types/ngwr-badge.d.ts +22 -7
  441. package/types/ngwr-config.d.ts +12 -0
  442. package/types/ngwr-editor-testing.d.ts +378 -0
  443. package/types/ngwr-editor.d.ts +449 -0
  444. package/types/ngwr-markdown.d.ts +61 -2
  445. package/types/ngwr-typography.d.ts +4 -0
  446. package/types/ngwr-version.d.ts +1 -1
  447. package/typography/styles/_index.scss +16 -0
@@ -101,10 +101,10 @@ class WrBytes {
101
101
  out.splice(at === 0 ? 1 : at, 0, ' ');
102
102
  return out.join('');
103
103
  }
104
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrBytes, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
105
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.6", ngImport: i0, type: WrBytes, isStandalone: true, name: "wrBytes" });
104
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrBytes, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
105
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.7", ngImport: i0, type: WrBytes, isStandalone: true, name: "wrBytes" });
106
106
  }
107
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrBytes, decorators: [{
107
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrBytes, decorators: [{
108
108
  type: Pipe,
109
109
  args: [{ name: 'wrBytes' }]
110
110
  }] });
@@ -155,10 +155,10 @@ class WrDate {
155
155
  const opts = named[format] ?? { dateStyle: 'short' };
156
156
  return new Intl.DateTimeFormat(this.locale, opts).format(date);
157
157
  }
158
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrDate, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
159
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.6", ngImport: i0, type: WrDate, isStandalone: true, name: "wrDate" });
158
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrDate, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
159
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.7", ngImport: i0, type: WrDate, isStandalone: true, name: "wrDate" });
160
160
  }
161
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrDate, decorators: [{
161
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrDate, decorators: [{
162
162
  type: Pipe,
163
163
  args: [{ name: 'wrDate' }]
164
164
  }] });
@@ -218,10 +218,10 @@ class WrMark {
218
218
  .join('');
219
219
  return this.sanitizer.bypassSecurityTrustHtml(html);
220
220
  }
221
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrMark, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
222
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.6", ngImport: i0, type: WrMark, isStandalone: true, name: "wrMark" });
221
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrMark, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
222
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.7", ngImport: i0, type: WrMark, isStandalone: true, name: "wrMark" });
223
223
  }
224
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrMark, decorators: [{
224
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrMark, decorators: [{
225
225
  type: Pipe,
226
226
  args: [{ name: 'wrMark' }]
227
227
  }] });
@@ -269,10 +269,10 @@ class WrNumber {
269
269
  return { style: 'decimal' };
270
270
  }
271
271
  }
272
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrNumber, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
273
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.6", ngImport: i0, type: WrNumber, isStandalone: true, name: "wrNumber" });
272
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrNumber, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
273
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.7", ngImport: i0, type: WrNumber, isStandalone: true, name: "wrNumber" });
274
274
  }
275
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrNumber, decorators: [{
275
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrNumber, decorators: [{
276
276
  type: Pipe,
277
277
  args: [{ name: 'wrNumber' }]
278
278
  }] });
@@ -315,10 +315,10 @@ class WrPlural {
315
315
  return word;
316
316
  return `${new Intl.NumberFormat(locale).format(value)} ${word}`;
317
317
  }
318
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrPlural, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
319
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.6", ngImport: i0, type: WrPlural, isStandalone: true, name: "wrPlural" });
318
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrPlural, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
319
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.7", ngImport: i0, type: WrPlural, isStandalone: true, name: "wrPlural" });
320
320
  }
321
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrPlural, decorators: [{
321
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrPlural, decorators: [{
322
322
  type: Pipe,
323
323
  args: [{ name: 'wrPlural' }]
324
324
  }] });
@@ -345,10 +345,10 @@ class WrRange {
345
345
  transform(length) {
346
346
  return Array.from({ length }, (_, i) => i);
347
347
  }
348
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrRange, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
349
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.6", ngImport: i0, type: WrRange, isStandalone: true, name: "wrRange" });
348
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrRange, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
349
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.7", ngImport: i0, type: WrRange, isStandalone: true, name: "wrRange" });
350
350
  }
351
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrRange, decorators: [{
351
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrRange, decorators: [{
352
352
  type: Pipe,
353
353
  args: [{ name: 'wrRange' }]
354
354
  }] });
@@ -377,10 +377,10 @@ class WrTruncate {
377
377
  return s;
378
378
  return s.slice(0, Math.max(0, length)) + ellipsis;
379
379
  }
380
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrTruncate, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
381
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.6", ngImport: i0, type: WrTruncate, isStandalone: true, name: "wrTruncate" });
380
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrTruncate, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
381
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.7", ngImport: i0, type: WrTruncate, isStandalone: true, name: "wrTruncate" });
382
382
  }
383
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrTruncate, decorators: [{
383
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrTruncate, decorators: [{
384
384
  type: Pipe,
385
385
  args: [{ name: 'wrTruncate' }]
386
386
  }] });
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-pipes.mjs","sources":["../../../projects/lib/pipes/bytes.ts","../../../projects/lib/pipes/date.ts","../../../projects/lib/pipes/mark.ts","../../../projects/lib/pipes/number.ts","../../../projects/lib/pipes/plural.ts","../../../projects/lib/pipes/range.ts","../../../projects/lib/pipes/truncate.ts","../../../projects/lib/pipes/ngwr-pipes.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 { LOCALE_ID, Pipe, inject } from '@angular/core';\nimport type { PipeTransform } from '@angular/core';\n\n/**\n * Binary magnitudes, as the `Intl` unit that labels each one. The COUNTING is\n * 1024-based and these names are decimal — which is the same thing the old\n * hand-written `['B', 'KB', 'MB', …]` table did, and what almost every file\n * manager does. Strictly, 1024 bytes is a kibibyte; `Intl` has no unit for it.\n */\nconst UNITS = ['byte', 'kilobyte', 'megabyte', 'gigabyte', 'terabyte', 'petabyte'] as const;\n\n/**\n * Humanise a byte count using binary (1024-based) units, in the reader's locale.\n *\n * @example\n * ```html\n * {{ 1234 | wrBytes }} <!-- en: \"1.2 kB\" de: \"1,2 kB\" ru: \"1,2 кБ\" -->\n * {{ 1234567 | wrBytes: 0 }} <!-- en: \"1 MB\" fr: \"1 Mo\" -->\n * {{ 0 | wrBytes }} <!-- en: \"0 B\" ru: \"0 Б\" -->\n * ```\n *\n * **Both halves come from `Intl`, and the unit table is not the catalog's.** The\n * number always did need `LOCALE_ID` — it went through `toFixed`, which writes a\n * full stop in every language, so a German page read `1.2 KB` beside its own\n * `1,2` everywhere else — and the three formatting pipes beside this one\n * (`wrDate`, `wrNumber`, `wrPlural`) had injected it since they shipped.\n *\n * The unit could not follow them into `ngwr/i18n`, and the reason is the pipe\n * rather than the strings: a PURE pipe is re-invoked only when its argument\n * changes, so a catalog that lands after the first render — which is every\n * `provideWrI18nHttpLoader` app — would never reach it, and the pipe would be\n * correct under the static loader and silently English under the other one.\n * `LOCALE_ID` is a constant, so `Intl` has no such failure mode, and it knows\n * every locale ICU ships rather than the twenty-two this package translates.\n *\n * One visible change in English and it is the only one: `KB` became `kB`, which\n * is what CLDR calls that unit. `B`, the space before it and every other\n * magnitude read exactly as they did — see `format` for the part of that which\n * is not free.\n *\n * The other consequence, kept here so nobody rediscovers it as a bug:\n * `<wr-file-upload>` prints its own sizes from `fileUpload.unitKb` and friends,\n * which are public catalog keys a consumer may have overridden, so it renders\n * `KB` where this pipe renders `kB`. Retiring those keys would silently break\n * every override that had been translating them, which is a major-version move.\n */\n@Pipe({ name: 'wrBytes' })\nexport class WrBytes implements PipeTransform {\n private readonly locale = inject(LOCALE_ID);\n\n transform(value: number | string | null | undefined, decimals = 1): string {\n if (value === null || value === undefined || value === '') return '';\n const n = Number(value);\n if (!Number.isFinite(n) || n <= 0) return this.format(0, 0, 0);\n\n // Floored as well as capped: for `0 < n < 1` the log is negative, so an\n // unclamped index reads `UNITS[-1]` (`undefined`) and divides by `1024 ** -1`,\n // which rendered `0.5` as \"512.0 undefined\".\n const i = Math.min(Math.max(0, Math.floor(Math.log(n) / Math.log(1024))), UNITS.length - 1);\n // Whole bytes never show a fractional part.\n return this.format(n / 1024 ** i, i, i === 0 ? 0 : Math.max(0, decimals));\n }\n\n /**\n * `Intl`'s NARROW unit, with one space put back between it and the number.\n *\n * Neither display mode is right on its own. `short` spells the smallest unit\n * as a word — \"512 byte\", \"0 byte\" in English, \"0 Byte\" in German — which is\n * both worse copy than the `B` this pipe has always rendered and a bigger\n * change than the fix is worth. `narrow` gives `B` / `Б` / `o` correctly and\n * then closes the gap: \"1.2kB\".\n *\n * So the parts are reassembled rather than the string. Going through\n * `formatToParts` is what keeps the ORDER the locale's own — Hebrew puts the\n * unit first, and hand-joining `${n} ${unit}` would silently straighten every\n * such locale into English order.\n */\n private format(value: number, unit: number, fractionDigits: number): string {\n const parts = new Intl.NumberFormat(this.locale, {\n style: 'unit',\n unit: UNITS[unit],\n unitDisplay: 'narrow',\n minimumFractionDigits: fractionDigits,\n maximumFractionDigits: fractionDigits,\n }).formatToParts(value);\n\n const at = parts.findIndex(part => part.type === 'unit');\n if (at === -1) return parts.map(part => part.value).join('');\n\n const out = parts.map(part => part.value);\n // The slot on the number's side of the unit: already a separator in some\n // locales, absent in others.\n const gap = at === 0 ? 1 : at - 1;\n if (parts[gap]?.type === 'literal') out[gap] = ' ';\n else out.splice(at === 0 ? 1 : at, 0, ' ');\n return out.join('');\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 { LOCALE_ID, Pipe, inject } from '@angular/core';\nimport type { PipeTransform } from '@angular/core';\n\nimport { type WrDateFormat, WrDateAdapter } from 'ngwr/date';\n\n/**\n * Locale-aware date formatting. Delegates to `WrDateAdapter` when\n * `provideWrDateAdapter()` is in the provider tree (giving access to named\n * format keys like `'shortDate'` and `'longDate'`), otherwise falls back to\n * a minimal `Intl.DateTimeFormat`-based formatter so the pipe still works\n * without the date-adapter package wired up.\n *\n * @example\n * ```html\n * {{ now | wrDate }} <!-- shortDate -->\n * {{ now | wrDate: 'mediumDateTime' }} <!-- named key -->\n * {{ now | wrDate: 'dd.MM.yyyy' }} <!-- raw token string -->\n * ```\n */\n@Pipe({ name: 'wrDate' })\nexport class WrDate implements PipeTransform {\n private readonly adapter = inject<WrDateAdapter<Date> | null>(WrDateAdapter, { optional: true });\n private readonly locale = inject(LOCALE_ID);\n\n transform(\n value: Date | string | number | null | undefined,\n format: WrDateFormat | (string & {}) = 'shortDate'\n ): string {\n if (value === null || value === undefined || value === '') return '';\n const date = value instanceof Date ? value : new Date(value);\n if (Number.isNaN(date.getTime())) return '';\n\n if (this.adapter) return this.adapter.format(date, format);\n return this.fallback(date, format);\n }\n\n /** Tiny fallback for the named keys when no adapter is provided. */\n private fallback(date: Date, format: WrDateFormat | (string & {})): string {\n const named: Record<string, Intl.DateTimeFormatOptions> = {\n shortDate: { dateStyle: 'short' },\n mediumDate: { dateStyle: 'medium' },\n longDate: { dateStyle: 'long' },\n time: { timeStyle: 'short' },\n shortDateTime: { dateStyle: 'short', timeStyle: 'short' },\n mediumDateTime: { dateStyle: 'medium', timeStyle: 'short' },\n };\n const opts = named[format] ?? { dateStyle: 'short' };\n return new Intl.DateTimeFormat(this.locale, opts).format(date);\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 { Pipe, type PipeTransform, inject } from '@angular/core';\nimport { DomSanitizer, type SafeHtml } from '@angular/platform-browser';\n\n/** Escapes RegExp metacharacters so user input is safe to inline. @internal */\nconst RE_META = /[\\\\^$.*+?()[\\]{}|]/g;\n\n/** HTML-entities for the four chars that matter inside our `<mark>` wrap. @internal */\nfunction escapeHtml(s: string): string {\n return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n}\n\n/**\n * Wrap every occurrence of `query` in `<mark>` tags. Useful for highlighting\n * search-term matches in autocomplete results, lists, and table cells.\n *\n * The output is `SafeHtml` — bind with `[innerHTML]`. Input is escaped first\n * so user-supplied values can't inject markup.\n *\n * @example\n * ```html\n * <span [innerHTML]=\"row.name | wrMark: query()\"></span>\n *\n * <!-- Case-sensitive: -->\n * <span [innerHTML]=\"row.name | wrMark: query() : true\"></span>\n * ```\n */\n@Pipe({ name: 'wrMark' })\nexport class WrMark implements PipeTransform {\n private readonly sanitizer = inject(DomSanitizer);\n\n /**\n * @param value Source text.\n * @param query Search term to highlight. Empty/null skips the wrap.\n * @param caseSensitive Match exactly. @default false\n */\n transform(value: string | null | undefined, query: string | null | undefined, caseSensitive = false): SafeHtml {\n if (value === null || value === undefined) return '';\n const text = String(value);\n if (!query) return text;\n\n // Match the RAW text and escape the pieces afterwards, never the other way\n // round. Escaping first rewrites `&` as `&amp;`, and a query of `m` then lands\n // INSIDE that entity: the `<mark>` splits it and the browser paints the\n // entity's own letters, so `Tom & Jerry` renders as `Tom &amp; Jerry`. The\n // mirror failure is a match that can never happen — `<`, `>` and `\"` no longer\n // exist in escaped text. The pipe's promise is untouched: every piece that came\n // from `value` still goes through `escapeHtml`, matched or not, so the only\n // tags in the output are the `<mark>`s built here.\n const pattern = new RegExp(`(${query.replace(RE_META, '\\\\$&')})`, caseSensitive ? 'g' : 'gi');\n const html = text\n .split(pattern)\n .map((part, index) => (index % 2 ? `<mark>${escapeHtml(part)}</mark>` : escapeHtml(part)))\n .join('');\n\n return this.sanitizer.bypassSecurityTrustHtml(html);\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 { LOCALE_ID, Pipe, inject } from '@angular/core';\nimport type { PipeTransform } from '@angular/core';\n\nimport type { WrNumberStyle } from './interfaces';\n\n/**\n * Locale-aware number formatting via `Intl.NumberFormat`. Uses Angular's\n * `LOCALE_ID` as the default locale.\n *\n * Accepts either a style shortcut (with optional currency code) or a full\n * `Intl.NumberFormatOptions` object for fine-grained control.\n *\n * @example\n * ```html\n * {{ 1234.5 | wrNumber }} <!-- \"1,234.5\" -->\n * {{ 0.875 | wrNumber: 'percent' }} <!-- \"88%\" -->\n * {{ 19.99 | wrNumber: 'currency': 'USD' }} <!-- \"$19.99\" -->\n * {{ 19.99 | wrNumber: { minimumFractionDigits: 2 } }}\n * ```\n */\n@Pipe({ name: 'wrNumber' })\nexport class WrNumber implements PipeTransform {\n private readonly locale = inject(LOCALE_ID);\n\n transform(\n value: number | string | null | undefined,\n styleOrOptions: WrNumberStyle | Intl.NumberFormatOptions = 'decimal',\n currency = 'USD'\n ): string {\n if (value === null || value === undefined || value === '') return '';\n const n = Number(value);\n if (!Number.isFinite(n)) return '';\n\n const options: Intl.NumberFormatOptions =\n typeof styleOrOptions === 'string' ? this.toOptions(styleOrOptions, currency) : styleOrOptions;\n\n return new Intl.NumberFormat(this.locale, options).format(n);\n }\n\n private toOptions(style: WrNumberStyle, currency: string): Intl.NumberFormatOptions {\n switch (style) {\n case 'percent':\n return { style: 'percent', maximumFractionDigits: 2 };\n case 'currency':\n return { style: 'currency', currency };\n case 'decimal':\n default:\n return { style: 'decimal' };\n }\n }\n}\n\nexport type { WrNumberStyle } from './interfaces';\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 { LOCALE_ID, Pipe, inject } from '@angular/core';\nimport type { PipeTransform } from '@angular/core';\n\nimport type { WrPluralForms, WrPluralOptions } from './interfaces';\n\n/**\n * Locale-aware pluralization via `Intl.PluralRules`. Picks the right word\n * form for the count — including languages with more than two forms\n * (Russian, Polish, Arabic, …) — without hand-rolled `n % 10` rules.\n *\n * Categories follow CLDR: `zero` / `one` / `two` / `few` / `many` /\n * `other`. Missing categories fall back to `other`.\n *\n * @example\n * ```html\n * {{ 1 | wrPlural: { one: 'comment', other: 'comments' } }}\n * <!-- \"1 comment\" -->\n *\n * {{ 5 | wrPlural: { one: 'файл', few: 'файла', other: 'файлов' } }}\n * <!-- \"5 файлов\" (with LOCALE_ID = ru) -->\n *\n * {{ count() | wrPlural: forms : { includeValue: false } }}\n * <!-- word only -->\n * ```\n */\n@Pipe({ name: 'wrPlural' })\nexport class WrPlural implements PipeTransform {\n private readonly locale = inject(LOCALE_ID);\n\n transform(value: number | null | undefined, forms: WrPluralForms, options: WrPluralOptions = {}): string {\n if (value === null || value === undefined || !Number.isFinite(value)) return '';\n const locale = options.locale ?? this.locale;\n const category = new Intl.PluralRules(locale).select(value);\n const word = forms[category] ?? forms.other;\n if (options.includeValue === false) return word;\n return `${new Intl.NumberFormat(locale).format(value)} ${word}`;\n }\n}\n\nexport type { WrPluralForms, WrPluralOptions } from './interfaces';\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 { Pipe } from '@angular/core';\nimport type { PipeTransform } from '@angular/core';\n\n/**\n * Creates an array of sequential indices `[0, 1, 2, ..., n-1]`.\n *\n * Useful for repeating template blocks a fixed number of times.\n *\n * @example\n * ```html\n * @for (i of (5 | wrRange); track i) {\n * <div>Item {{ i }}</div>\n * }\n * ```\n */\n@Pipe({ name: 'wrRange' })\nexport class WrRange implements PipeTransform {\n transform(length: number): number[] {\n return Array.from({ length }, (_, i) => i);\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 { Pipe } from '@angular/core';\nimport type { PipeTransform } from '@angular/core';\n\n/**\n * Clamp a string to `length` characters, appending `ellipsis` when truncated.\n *\n * @example\n * ```html\n * {{ 'Hello, world' | wrTruncate: 5 }} <!-- \"Hello…\" -->\n * {{ 'Hello, world' | wrTruncate: 8: '...' }} <!-- \"Hello, w...\" -->\n * ```\n */\n@Pipe({ name: 'wrTruncate' })\nexport class WrTruncate implements PipeTransform {\n transform(value: string | null | undefined, length = 80, ellipsis = '…'): string {\n if (value === null || value === undefined) return '';\n const s = String(value);\n if (s.length <= length) return s;\n return s.slice(0, Math.max(0, length)) + ellipsis;\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-pipes.mjs","sources":["../../../projects/lib/pipes/bytes.ts","../../../projects/lib/pipes/date.ts","../../../projects/lib/pipes/mark.ts","../../../projects/lib/pipes/number.ts","../../../projects/lib/pipes/plural.ts","../../../projects/lib/pipes/range.ts","../../../projects/lib/pipes/truncate.ts","../../../projects/lib/pipes/ngwr-pipes.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 { LOCALE_ID, Pipe, inject } from '@angular/core';\nimport type { PipeTransform } from '@angular/core';\n\n/**\n * Binary magnitudes, as the `Intl` unit that labels each one. The COUNTING is\n * 1024-based and these names are decimal — which is the same thing the old\n * hand-written `['B', 'KB', 'MB', …]` table did, and what almost every file\n * manager does. Strictly, 1024 bytes is a kibibyte; `Intl` has no unit for it.\n */\nconst UNITS = ['byte', 'kilobyte', 'megabyte', 'gigabyte', 'terabyte', 'petabyte'] as const;\n\n/**\n * Humanise a byte count using binary (1024-based) units, in the reader's locale.\n *\n * @example\n * ```html\n * {{ 1234 | wrBytes }} <!-- en: \"1.2 kB\" de: \"1,2 kB\" ru: \"1,2 кБ\" -->\n * {{ 1234567 | wrBytes: 0 }} <!-- en: \"1 MB\" fr: \"1 Mo\" -->\n * {{ 0 | wrBytes }} <!-- en: \"0 B\" ru: \"0 Б\" -->\n * ```\n *\n * **Both halves come from `Intl`, and the unit table is not the catalog's.** The\n * number always did need `LOCALE_ID` — it went through `toFixed`, which writes a\n * full stop in every language, so a German page read `1.2 KB` beside its own\n * `1,2` everywhere else — and the three formatting pipes beside this one\n * (`wrDate`, `wrNumber`, `wrPlural`) had injected it since they shipped.\n *\n * The unit could not follow them into `ngwr/i18n`, and the reason is the pipe\n * rather than the strings: a PURE pipe is re-invoked only when its argument\n * changes, so a catalog that lands after the first render — which is every\n * `provideWrI18nHttpLoader` app — would never reach it, and the pipe would be\n * correct under the static loader and silently English under the other one.\n * `LOCALE_ID` is a constant, so `Intl` has no such failure mode, and it knows\n * every locale ICU ships rather than the twenty-two this package translates.\n *\n * One visible change in English and it is the only one: `KB` became `kB`, which\n * is what CLDR calls that unit. `B`, the space before it and every other\n * magnitude read exactly as they did — see `format` for the part of that which\n * is not free.\n *\n * The other consequence, kept here so nobody rediscovers it as a bug:\n * `<wr-file-upload>` prints its own sizes from `fileUpload.unitKb` and friends,\n * which are public catalog keys a consumer may have overridden, so it renders\n * `KB` where this pipe renders `kB`. Retiring those keys would silently break\n * every override that had been translating them, which is a major-version move.\n */\n@Pipe({ name: 'wrBytes' })\nexport class WrBytes implements PipeTransform {\n private readonly locale = inject(LOCALE_ID);\n\n transform(value: number | string | null | undefined, decimals = 1): string {\n if (value === null || value === undefined || value === '') return '';\n const n = Number(value);\n if (!Number.isFinite(n) || n <= 0) return this.format(0, 0, 0);\n\n // Floored as well as capped: for `0 < n < 1` the log is negative, so an\n // unclamped index reads `UNITS[-1]` (`undefined`) and divides by `1024 ** -1`,\n // which rendered `0.5` as \"512.0 undefined\".\n const i = Math.min(Math.max(0, Math.floor(Math.log(n) / Math.log(1024))), UNITS.length - 1);\n // Whole bytes never show a fractional part.\n return this.format(n / 1024 ** i, i, i === 0 ? 0 : Math.max(0, decimals));\n }\n\n /**\n * `Intl`'s NARROW unit, with one space put back between it and the number.\n *\n * Neither display mode is right on its own. `short` spells the smallest unit\n * as a word — \"512 byte\", \"0 byte\" in English, \"0 Byte\" in German — which is\n * both worse copy than the `B` this pipe has always rendered and a bigger\n * change than the fix is worth. `narrow` gives `B` / `Б` / `o` correctly and\n * then closes the gap: \"1.2kB\".\n *\n * So the parts are reassembled rather than the string. Going through\n * `formatToParts` is what keeps the ORDER the locale's own — Hebrew puts the\n * unit first, and hand-joining `${n} ${unit}` would silently straighten every\n * such locale into English order.\n */\n private format(value: number, unit: number, fractionDigits: number): string {\n const parts = new Intl.NumberFormat(this.locale, {\n style: 'unit',\n unit: UNITS[unit],\n unitDisplay: 'narrow',\n minimumFractionDigits: fractionDigits,\n maximumFractionDigits: fractionDigits,\n }).formatToParts(value);\n\n const at = parts.findIndex(part => part.type === 'unit');\n if (at === -1) return parts.map(part => part.value).join('');\n\n const out = parts.map(part => part.value);\n // The slot on the number's side of the unit: already a separator in some\n // locales, absent in others.\n const gap = at === 0 ? 1 : at - 1;\n if (parts[gap]?.type === 'literal') out[gap] = ' ';\n else out.splice(at === 0 ? 1 : at, 0, ' ');\n return out.join('');\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 { LOCALE_ID, Pipe, inject } from '@angular/core';\nimport type { PipeTransform } from '@angular/core';\n\nimport { type WrDateFormat, WrDateAdapter } from 'ngwr/date';\n\n/**\n * Locale-aware date formatting. Delegates to `WrDateAdapter` when\n * `provideWrDateAdapter()` is in the provider tree (giving access to named\n * format keys like `'shortDate'` and `'longDate'`), otherwise falls back to\n * a minimal `Intl.DateTimeFormat`-based formatter so the pipe still works\n * without the date-adapter package wired up.\n *\n * @example\n * ```html\n * {{ now | wrDate }} <!-- shortDate -->\n * {{ now | wrDate: 'mediumDateTime' }} <!-- named key -->\n * {{ now | wrDate: 'dd.MM.yyyy' }} <!-- raw token string -->\n * ```\n */\n@Pipe({ name: 'wrDate' })\nexport class WrDate implements PipeTransform {\n private readonly adapter = inject<WrDateAdapter<Date> | null>(WrDateAdapter, { optional: true });\n private readonly locale = inject(LOCALE_ID);\n\n transform(\n value: Date | string | number | null | undefined,\n format: WrDateFormat | (string & {}) = 'shortDate'\n ): string {\n if (value === null || value === undefined || value === '') return '';\n const date = value instanceof Date ? value : new Date(value);\n if (Number.isNaN(date.getTime())) return '';\n\n if (this.adapter) return this.adapter.format(date, format);\n return this.fallback(date, format);\n }\n\n /** Tiny fallback for the named keys when no adapter is provided. */\n private fallback(date: Date, format: WrDateFormat | (string & {})): string {\n const named: Record<string, Intl.DateTimeFormatOptions> = {\n shortDate: { dateStyle: 'short' },\n mediumDate: { dateStyle: 'medium' },\n longDate: { dateStyle: 'long' },\n time: { timeStyle: 'short' },\n shortDateTime: { dateStyle: 'short', timeStyle: 'short' },\n mediumDateTime: { dateStyle: 'medium', timeStyle: 'short' },\n };\n const opts = named[format] ?? { dateStyle: 'short' };\n return new Intl.DateTimeFormat(this.locale, opts).format(date);\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 { Pipe, type PipeTransform, inject } from '@angular/core';\nimport { DomSanitizer, type SafeHtml } from '@angular/platform-browser';\n\n/** Escapes RegExp metacharacters so user input is safe to inline. @internal */\nconst RE_META = /[\\\\^$.*+?()[\\]{}|]/g;\n\n/** HTML-entities for the four chars that matter inside our `<mark>` wrap. @internal */\nfunction escapeHtml(s: string): string {\n return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n}\n\n/**\n * Wrap every occurrence of `query` in `<mark>` tags. Useful for highlighting\n * search-term matches in autocomplete results, lists, and table cells.\n *\n * The output is `SafeHtml` — bind with `[innerHTML]`. Input is escaped first\n * so user-supplied values can't inject markup.\n *\n * @example\n * ```html\n * <span [innerHTML]=\"row.name | wrMark: query()\"></span>\n *\n * <!-- Case-sensitive: -->\n * <span [innerHTML]=\"row.name | wrMark: query() : true\"></span>\n * ```\n */\n@Pipe({ name: 'wrMark' })\nexport class WrMark implements PipeTransform {\n private readonly sanitizer = inject(DomSanitizer);\n\n /**\n * @param value Source text.\n * @param query Search term to highlight. Empty/null skips the wrap.\n * @param caseSensitive Match exactly. @default false\n */\n transform(value: string | null | undefined, query: string | null | undefined, caseSensitive = false): SafeHtml {\n if (value === null || value === undefined) return '';\n const text = String(value);\n if (!query) return text;\n\n // Match the RAW text and escape the pieces afterwards, never the other way\n // round. Escaping first rewrites `&` as `&amp;`, and a query of `m` then lands\n // INSIDE that entity: the `<mark>` splits it and the browser paints the\n // entity's own letters, so `Tom & Jerry` renders as `Tom &amp; Jerry`. The\n // mirror failure is a match that can never happen — `<`, `>` and `\"` no longer\n // exist in escaped text. The pipe's promise is untouched: every piece that came\n // from `value` still goes through `escapeHtml`, matched or not, so the only\n // tags in the output are the `<mark>`s built here.\n const pattern = new RegExp(`(${query.replace(RE_META, '\\\\$&')})`, caseSensitive ? 'g' : 'gi');\n const html = text\n .split(pattern)\n .map((part, index) => (index % 2 ? `<mark>${escapeHtml(part)}</mark>` : escapeHtml(part)))\n .join('');\n\n return this.sanitizer.bypassSecurityTrustHtml(html);\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 { LOCALE_ID, Pipe, inject } from '@angular/core';\nimport type { PipeTransform } from '@angular/core';\n\nimport type { WrNumberStyle } from './interfaces';\n\n/**\n * Locale-aware number formatting via `Intl.NumberFormat`. Uses Angular's\n * `LOCALE_ID` as the default locale.\n *\n * Accepts either a style shortcut (with optional currency code) or a full\n * `Intl.NumberFormatOptions` object for fine-grained control.\n *\n * @example\n * ```html\n * {{ 1234.5 | wrNumber }} <!-- \"1,234.5\" -->\n * {{ 0.875 | wrNumber: 'percent' }} <!-- \"88%\" -->\n * {{ 19.99 | wrNumber: 'currency': 'USD' }} <!-- \"$19.99\" -->\n * {{ 19.99 | wrNumber: { minimumFractionDigits: 2 } }}\n * ```\n */\n@Pipe({ name: 'wrNumber' })\nexport class WrNumber implements PipeTransform {\n private readonly locale = inject(LOCALE_ID);\n\n transform(\n value: number | string | null | undefined,\n styleOrOptions: WrNumberStyle | Intl.NumberFormatOptions = 'decimal',\n currency = 'USD'\n ): string {\n if (value === null || value === undefined || value === '') return '';\n const n = Number(value);\n if (!Number.isFinite(n)) return '';\n\n const options: Intl.NumberFormatOptions =\n typeof styleOrOptions === 'string' ? this.toOptions(styleOrOptions, currency) : styleOrOptions;\n\n return new Intl.NumberFormat(this.locale, options).format(n);\n }\n\n private toOptions(style: WrNumberStyle, currency: string): Intl.NumberFormatOptions {\n switch (style) {\n case 'percent':\n return { style: 'percent', maximumFractionDigits: 2 };\n case 'currency':\n return { style: 'currency', currency };\n case 'decimal':\n default:\n return { style: 'decimal' };\n }\n }\n}\n\nexport type { WrNumberStyle } from './interfaces';\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 { LOCALE_ID, Pipe, inject } from '@angular/core';\nimport type { PipeTransform } from '@angular/core';\n\nimport type { WrPluralForms, WrPluralOptions } from './interfaces';\n\n/**\n * Locale-aware pluralization via `Intl.PluralRules`. Picks the right word\n * form for the count — including languages with more than two forms\n * (Russian, Polish, Arabic, …) — without hand-rolled `n % 10` rules.\n *\n * Categories follow CLDR: `zero` / `one` / `two` / `few` / `many` /\n * `other`. Missing categories fall back to `other`.\n *\n * @example\n * ```html\n * {{ 1 | wrPlural: { one: 'comment', other: 'comments' } }}\n * <!-- \"1 comment\" -->\n *\n * {{ 5 | wrPlural: { one: 'файл', few: 'файла', other: 'файлов' } }}\n * <!-- \"5 файлов\" (with LOCALE_ID = ru) -->\n *\n * {{ count() | wrPlural: forms : { includeValue: false } }}\n * <!-- word only -->\n * ```\n */\n@Pipe({ name: 'wrPlural' })\nexport class WrPlural implements PipeTransform {\n private readonly locale = inject(LOCALE_ID);\n\n transform(value: number | null | undefined, forms: WrPluralForms, options: WrPluralOptions = {}): string {\n if (value === null || value === undefined || !Number.isFinite(value)) return '';\n const locale = options.locale ?? this.locale;\n const category = new Intl.PluralRules(locale).select(value);\n const word = forms[category] ?? forms.other;\n if (options.includeValue === false) return word;\n return `${new Intl.NumberFormat(locale).format(value)} ${word}`;\n }\n}\n\nexport type { WrPluralForms, WrPluralOptions } from './interfaces';\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 { Pipe } from '@angular/core';\nimport type { PipeTransform } from '@angular/core';\n\n/**\n * Creates an array of sequential indices `[0, 1, 2, ..., n-1]`.\n *\n * Useful for repeating template blocks a fixed number of times.\n *\n * @example\n * ```html\n * @for (i of (5 | wrRange); track i) {\n * <div>Item {{ i }}</div>\n * }\n * ```\n */\n@Pipe({ name: 'wrRange' })\nexport class WrRange implements PipeTransform {\n transform(length: number): number[] {\n return Array.from({ length }, (_, i) => i);\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 { Pipe } from '@angular/core';\nimport type { PipeTransform } from '@angular/core';\n\n/**\n * Clamp a string to `length` characters, appending `ellipsis` when truncated.\n *\n * @example\n * ```html\n * {{ 'Hello, world' | wrTruncate: 5 }} <!-- \"Hello…\" -->\n * {{ 'Hello, world' | wrTruncate: 8: '...' }} <!-- \"Hello, w...\" -->\n * ```\n */\n@Pipe({ name: 'wrTruncate' })\nexport class WrTruncate implements PipeTransform {\n transform(value: string | null | undefined, length = 80, ellipsis = '…'): string {\n if (value === null || value === undefined) return '';\n const s = String(value);\n if (s.length <= length) return s;\n return s.slice(0, Math.max(0, length)) + ellipsis;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -48,10 +48,10 @@ class WrPlatform {
48
48
  this.destroyRef.onDestroy(() => mql.removeEventListener('change', handler));
49
49
  return sig.asReadonly();
50
50
  }
51
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrPlatform, deps: [], target: i0.ɵɵFactoryTarget.Service });
52
- static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.6", ngImport: i0, type: WrPlatform });
51
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrPlatform, deps: [], target: i0.ɵɵFactoryTarget.Service });
52
+ static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.7", ngImport: i0, type: WrPlatform });
53
53
  }
54
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrPlatform, decorators: [{
54
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrPlatform, decorators: [{
55
55
  type: Service
56
56
  }] });
57
57
 
@@ -110,10 +110,10 @@ class WrVisualViewport {
110
110
  root.style.removeProperty('--wr-keyboard-inset');
111
111
  });
112
112
  }
113
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrVisualViewport, deps: [], target: i0.ɵɵFactoryTarget.Service });
114
- static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.6", ngImport: i0, type: WrVisualViewport });
113
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrVisualViewport, deps: [], target: i0.ɵɵFactoryTarget.Service });
114
+ static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.7", ngImport: i0, type: WrVisualViewport });
115
115
  }
116
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrVisualViewport, decorators: [{
116
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrVisualViewport, decorators: [{
117
117
  type: Service
118
118
  }], ctorParameters: () => [] });
119
119
 
@@ -212,10 +212,10 @@ class WrHaptics {
212
212
  stop() {
213
213
  this.vibrate(0);
214
214
  }
215
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrHaptics, deps: [], target: i0.ɵɵFactoryTarget.Service });
216
- static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.6", ngImport: i0, type: WrHaptics });
215
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrHaptics, deps: [], target: i0.ɵɵFactoryTarget.Service });
216
+ static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.7", ngImport: i0, type: WrHaptics });
217
217
  }
218
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrHaptics, decorators: [{
218
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrHaptics, decorators: [{
219
219
  type: Service
220
220
  }] });
221
221
 
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-platform.mjs","sources":["../../../projects/lib/platform/wr-platform.ts","../../../projects/lib/platform/wr-visual-viewport.ts","../../../projects/lib/platform/wr-haptics.ts","../../../projects/lib/platform/ngwr-platform.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 { DOCUMENT, isPlatformBrowser } from '@angular/common';\nimport { DestroyRef, Service, PLATFORM_ID, type Signal, inject, signal } from '@angular/core';\n\n/**\n * SSR-safe environment probes. Use to gate browser-only code paths and\n * react to user preferences without scattering `matchMedia` calls around.\n *\n * - `isBrowser` / `isServer` — synchronous platform check.\n * - `userAgent` — `navigator.userAgent` or `null` on the server.\n * - `prefersDark` — signal mirroring `(prefers-color-scheme: dark)`.\n * - `prefersReducedMotion` — signal mirroring `(prefers-reduced-motion: reduce)`.\n *\n * @example\n * ```ts\n * private readonly platform = inject(WrPlatform);\n * if (this.platform.isBrowser) {\n * localStorage.setItem('theme', 'dark');\n * }\n *\n * protected readonly dark = this.platform.prefersDark;\n * ```\n *\n * @see https://ngwr.dev/reference/services/platform\n */\n@Service()\nexport class WrPlatform {\n private readonly destroyRef = inject(DestroyRef);\n private readonly doc = inject(DOCUMENT);\n\n readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n readonly isServer = !this.isBrowser;\n readonly userAgent: string | null = this.isBrowser ? (this.doc.defaultView?.navigator?.userAgent ?? null) : null;\n\n readonly prefersDark: Signal<boolean> = this.mediaSignal('(prefers-color-scheme: dark)');\n readonly prefersReducedMotion: Signal<boolean> = this.mediaSignal('(prefers-reduced-motion: reduce)');\n\n private mediaSignal(query: string): Signal<boolean> {\n if (!this.isBrowser || !this.doc.defaultView?.matchMedia) return signal(false).asReadonly();\n const mql = this.doc.defaultView.matchMedia(query);\n const sig = signal(mql.matches);\n const handler = (event: MediaQueryListEvent): void => sig.set(event.matches);\n mql.addEventListener('change', handler);\n this.destroyRef.onDestroy(() => mql.removeEventListener('change', handler));\n return sig.asReadonly();\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, isPlatformBrowser } from '@angular/common';\nimport { DestroyRef, PLATFORM_ID, Service, type Signal, inject, signal } from '@angular/core';\n\n/**\n * SSR-safe view onto `window.visualViewport` — the part of the layout viewport\n * actually visible once the on-screen keyboard (or other browser chrome) is\n * accounted for.\n *\n * - `bottomInset` — px hidden at the bottom of the layout viewport (the\n * keyboard height); `0` when nothing covers it, on the server, or in browsers\n * without the API.\n * - `offsetTop` — how far the visual viewport is pushed/scrolled down.\n *\n * While active it also mirrors `bottomInset` onto `--wr-keyboard-inset` on the\n * document root, so purely presentational surfaces (the responsive overlay\n * sheet, the command-palette sheet) can lift above the keyboard with CSS alone.\n *\n * @see https://ngwr.dev/reference/services/platform\n */\n@Service()\nexport class WrVisualViewport {\n private readonly destroyRef = inject(DestroyRef);\n private readonly doc = inject(DOCUMENT);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n private readonly _bottomInset = signal(0);\n private readonly _offsetTop = signal(0);\n\n /** Height (px) the keyboard / browser chrome hides at the viewport bottom. */\n readonly bottomInset: Signal<number> = this._bottomInset.asReadonly();\n /** The visual viewport's top offset (px). */\n readonly offsetTop: Signal<number> = this._offsetTop.asReadonly();\n\n constructor() {\n const vv = this.isBrowser ? this.doc.defaultView?.visualViewport : null;\n if (!vv) return;\n\n const root = this.doc.documentElement;\n const update = (): void => {\n // The band below the visual viewport, in layout-viewport coordinates.\n const bottom = Math.max(0, root.clientHeight - (vv.height + vv.offsetTop));\n this._bottomInset.set(bottom);\n this._offsetTop.set(vv.offsetTop);\n root.style.setProperty('--wr-keyboard-inset', `${bottom}px`);\n };\n\n update();\n vv.addEventListener('resize', update);\n vv.addEventListener('scroll', update);\n this.destroyRef.onDestroy(() => {\n vv.removeEventListener('resize', update);\n vv.removeEventListener('scroll', update);\n root.style.removeProperty('--wr-keyboard-inset');\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, isPlatformBrowser } from '@angular/common';\nimport { PLATFORM_ID, Service, inject } from '@angular/core';\n\n/** Impact weight for {@link WrHaptics.impact}. */\ntype WrHapticImpact = 'light' | 'medium' | 'heavy';\n\n/**\n * Vibration patterns (ms, or `[buzz, pause, buzz, …]`) behind the semantic\n * presets — loosely modelled on iOS's impact / notification feedback.\n */\nconst PATTERNS = {\n light: 10,\n medium: 20,\n heavy: 40,\n selection: 5,\n success: [15, 60, 30],\n warning: [30, 40, 30],\n error: [40, 60, 40, 60, 40],\n} as const;\n\n/**\n * SSR-safe wrapper around the Vibration API for tactile feedback on touch\n * devices. Semantic presets (`impact`, `selection`, `success`, `warning`,\n * `error`) map to sensible vibration patterns so call sites stay readable.\n *\n * Every method is a no-op — returning `false` — when there is no support:\n * on the server, in browsers without `navigator.vibrate`, and notably on\n * **iOS Safari**, which does not expose the Vibration API at all (its\n * haptics are native-only). Check {@link supported} to branch UI on it.\n *\n * Haptics are best paired with a real user gesture (tap) — some browsers\n * ignore `vibrate()` calls that aren't triggered by one. This service does\n * not gate on `prefers-reduced-motion`; read {@link WrPlatform.prefersReducedMotion}\n * at the call site if you want to suppress feedback for those users.\n *\n * @example\n * ```ts\n * private readonly haptics = inject(WrHaptics);\n *\n * onDelete(): void {\n * this.haptics.warning(); // buzz before a destructive confirm\n * }\n *\n * onToggle(): void {\n * this.haptics.selection(); // subtle tick on a switch / segmented change\n * }\n * ```\n *\n * @see https://ngwr.dev/reference/services/platform\n */\n@Service()\nexport class WrHaptics {\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n private readonly nav = this.isBrowser ? (inject(DOCUMENT).defaultView?.navigator ?? null) : null;\n\n /** Whether the Vibration API is available (browser + `navigator.vibrate`). */\n readonly supported: boolean = !!this.nav && typeof this.nav.vibrate === 'function';\n\n /**\n * Fire a raw vibration pattern — a single duration in ms, or an alternating\n * `[buzz, pause, buzz, …]` array. Returns whether it was dispatched; passing\n * `0` / `[]` cancels any ongoing vibration.\n */\n vibrate(pattern: number | readonly number[]): boolean {\n if (!this.supported) return false;\n try {\n // `VibratePattern` is `number | number[]`; readonly arrays are accepted\n // at runtime, so clone to satisfy the mutable-array signature.\n return this.nav!.vibrate(typeof pattern === 'number' ? pattern : [...pattern]);\n } catch {\n return false;\n }\n }\n\n /** A physical \"tap\" — `light`, `medium` (default), or `heavy`. */\n impact(strength: WrHapticImpact = 'medium'): boolean {\n return this.vibrate(PATTERNS[strength]);\n }\n\n /** A subtle tick for a discrete change (switch, segmented, stepper). */\n selection(): boolean {\n return this.vibrate(PATTERNS.selection);\n }\n\n /** A confirming pulse for a completed action. */\n success(): boolean {\n return this.vibrate(PATTERNS.success);\n }\n\n /** A cautioning pulse before a risky or destructive action. */\n warning(): boolean {\n return this.vibrate(PATTERNS.warning);\n }\n\n /** A buzzing pulse for a failure or rejected action. */\n error(): boolean {\n return this.vibrate(PATTERNS.error);\n }\n\n /** Cancel any in-progress vibration. */\n stop(): void {\n this.vibrate(0);\n }\n}\n\nexport type { WrHapticImpact };\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-platform.mjs","sources":["../../../projects/lib/platform/wr-platform.ts","../../../projects/lib/platform/wr-visual-viewport.ts","../../../projects/lib/platform/wr-haptics.ts","../../../projects/lib/platform/ngwr-platform.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 { DOCUMENT, isPlatformBrowser } from '@angular/common';\nimport { DestroyRef, Service, PLATFORM_ID, type Signal, inject, signal } from '@angular/core';\n\n/**\n * SSR-safe environment probes. Use to gate browser-only code paths and\n * react to user preferences without scattering `matchMedia` calls around.\n *\n * - `isBrowser` / `isServer` — synchronous platform check.\n * - `userAgent` — `navigator.userAgent` or `null` on the server.\n * - `prefersDark` — signal mirroring `(prefers-color-scheme: dark)`.\n * - `prefersReducedMotion` — signal mirroring `(prefers-reduced-motion: reduce)`.\n *\n * @example\n * ```ts\n * private readonly platform = inject(WrPlatform);\n * if (this.platform.isBrowser) {\n * localStorage.setItem('theme', 'dark');\n * }\n *\n * protected readonly dark = this.platform.prefersDark;\n * ```\n *\n * @see https://ngwr.dev/reference/services/platform\n */\n@Service()\nexport class WrPlatform {\n private readonly destroyRef = inject(DestroyRef);\n private readonly doc = inject(DOCUMENT);\n\n readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n readonly isServer = !this.isBrowser;\n readonly userAgent: string | null = this.isBrowser ? (this.doc.defaultView?.navigator?.userAgent ?? null) : null;\n\n readonly prefersDark: Signal<boolean> = this.mediaSignal('(prefers-color-scheme: dark)');\n readonly prefersReducedMotion: Signal<boolean> = this.mediaSignal('(prefers-reduced-motion: reduce)');\n\n private mediaSignal(query: string): Signal<boolean> {\n if (!this.isBrowser || !this.doc.defaultView?.matchMedia) return signal(false).asReadonly();\n const mql = this.doc.defaultView.matchMedia(query);\n const sig = signal(mql.matches);\n const handler = (event: MediaQueryListEvent): void => sig.set(event.matches);\n mql.addEventListener('change', handler);\n this.destroyRef.onDestroy(() => mql.removeEventListener('change', handler));\n return sig.asReadonly();\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, isPlatformBrowser } from '@angular/common';\nimport { DestroyRef, PLATFORM_ID, Service, type Signal, inject, signal } from '@angular/core';\n\n/**\n * SSR-safe view onto `window.visualViewport` — the part of the layout viewport\n * actually visible once the on-screen keyboard (or other browser chrome) is\n * accounted for.\n *\n * - `bottomInset` — px hidden at the bottom of the layout viewport (the\n * keyboard height); `0` when nothing covers it, on the server, or in browsers\n * without the API.\n * - `offsetTop` — how far the visual viewport is pushed/scrolled down.\n *\n * While active it also mirrors `bottomInset` onto `--wr-keyboard-inset` on the\n * document root, so purely presentational surfaces (the responsive overlay\n * sheet, the command-palette sheet) can lift above the keyboard with CSS alone.\n *\n * @see https://ngwr.dev/reference/services/platform\n */\n@Service()\nexport class WrVisualViewport {\n private readonly destroyRef = inject(DestroyRef);\n private readonly doc = inject(DOCUMENT);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n private readonly _bottomInset = signal(0);\n private readonly _offsetTop = signal(0);\n\n /** Height (px) the keyboard / browser chrome hides at the viewport bottom. */\n readonly bottomInset: Signal<number> = this._bottomInset.asReadonly();\n /** The visual viewport's top offset (px). */\n readonly offsetTop: Signal<number> = this._offsetTop.asReadonly();\n\n constructor() {\n const vv = this.isBrowser ? this.doc.defaultView?.visualViewport : null;\n if (!vv) return;\n\n const root = this.doc.documentElement;\n const update = (): void => {\n // The band below the visual viewport, in layout-viewport coordinates.\n const bottom = Math.max(0, root.clientHeight - (vv.height + vv.offsetTop));\n this._bottomInset.set(bottom);\n this._offsetTop.set(vv.offsetTop);\n root.style.setProperty('--wr-keyboard-inset', `${bottom}px`);\n };\n\n update();\n vv.addEventListener('resize', update);\n vv.addEventListener('scroll', update);\n this.destroyRef.onDestroy(() => {\n vv.removeEventListener('resize', update);\n vv.removeEventListener('scroll', update);\n root.style.removeProperty('--wr-keyboard-inset');\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, isPlatformBrowser } from '@angular/common';\nimport { PLATFORM_ID, Service, inject } from '@angular/core';\n\n/** Impact weight for {@link WrHaptics.impact}. */\ntype WrHapticImpact = 'light' | 'medium' | 'heavy';\n\n/**\n * Vibration patterns (ms, or `[buzz, pause, buzz, …]`) behind the semantic\n * presets — loosely modelled on iOS's impact / notification feedback.\n */\nconst PATTERNS = {\n light: 10,\n medium: 20,\n heavy: 40,\n selection: 5,\n success: [15, 60, 30],\n warning: [30, 40, 30],\n error: [40, 60, 40, 60, 40],\n} as const;\n\n/**\n * SSR-safe wrapper around the Vibration API for tactile feedback on touch\n * devices. Semantic presets (`impact`, `selection`, `success`, `warning`,\n * `error`) map to sensible vibration patterns so call sites stay readable.\n *\n * Every method is a no-op — returning `false` — when there is no support:\n * on the server, in browsers without `navigator.vibrate`, and notably on\n * **iOS Safari**, which does not expose the Vibration API at all (its\n * haptics are native-only). Check {@link supported} to branch UI on it.\n *\n * Haptics are best paired with a real user gesture (tap) — some browsers\n * ignore `vibrate()` calls that aren't triggered by one. This service does\n * not gate on `prefers-reduced-motion`; read {@link WrPlatform.prefersReducedMotion}\n * at the call site if you want to suppress feedback for those users.\n *\n * @example\n * ```ts\n * private readonly haptics = inject(WrHaptics);\n *\n * onDelete(): void {\n * this.haptics.warning(); // buzz before a destructive confirm\n * }\n *\n * onToggle(): void {\n * this.haptics.selection(); // subtle tick on a switch / segmented change\n * }\n * ```\n *\n * @see https://ngwr.dev/reference/services/platform\n */\n@Service()\nexport class WrHaptics {\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n private readonly nav = this.isBrowser ? (inject(DOCUMENT).defaultView?.navigator ?? null) : null;\n\n /** Whether the Vibration API is available (browser + `navigator.vibrate`). */\n readonly supported: boolean = !!this.nav && typeof this.nav.vibrate === 'function';\n\n /**\n * Fire a raw vibration pattern — a single duration in ms, or an alternating\n * `[buzz, pause, buzz, …]` array. Returns whether it was dispatched; passing\n * `0` / `[]` cancels any ongoing vibration.\n */\n vibrate(pattern: number | readonly number[]): boolean {\n if (!this.supported) return false;\n try {\n // `VibratePattern` is `number | number[]`; readonly arrays are accepted\n // at runtime, so clone to satisfy the mutable-array signature.\n return this.nav!.vibrate(typeof pattern === 'number' ? pattern : [...pattern]);\n } catch {\n return false;\n }\n }\n\n /** A physical \"tap\" — `light`, `medium` (default), or `heavy`. */\n impact(strength: WrHapticImpact = 'medium'): boolean {\n return this.vibrate(PATTERNS[strength]);\n }\n\n /** A subtle tick for a discrete change (switch, segmented, stepper). */\n selection(): boolean {\n return this.vibrate(PATTERNS.selection);\n }\n\n /** A confirming pulse for a completed action. */\n success(): boolean {\n return this.vibrate(PATTERNS.success);\n }\n\n /** A cautioning pulse before a risky or destructive action. */\n warning(): boolean {\n return this.vibrate(PATTERNS.warning);\n }\n\n /** A buzzing pulse for a failure or rejected action. */\n error(): boolean {\n return this.vibrate(PATTERNS.error);\n }\n\n /** Cancel any in-progress vibration. */\n stop(): void {\n this.vibrate(0);\n }\n}\n\nexport type { WrHapticImpact };\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-popconfirm-testing.mjs","sources":["../../../projects/lib/popconfirm/testing/wr-popconfirm-harness.ts","../../../projects/lib/popconfirm/testing/ngwr-popconfirm-testing.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 {\n ContentContainerComponentHarness,\n type HarnessLoader,\n HarnessPredicate,\n TestKey,\n type TestElement,\n} from '@angular/cdk/testing';\n\nimport type { WrPopconfirmPosition } from 'ngwr/popconfirm';\nimport { WR_COLORS, type WrColor } from 'ngwr/theme';\n\nimport type { WrPopconfirmHarnessFilters } from './interfaces';\n\n/** The two answers a popconfirm offers, which are also its two action modifiers. */\ntype WrPopconfirmAction = 'confirm' | 'cancel';\n\n/**\n * Test harness for `[wrPopconfirm]` — the \"are you sure?\" dialog anchored to its\n * trigger.\n *\n * The panel is NOT inside the trigger: it is a component portal in the overlay\n * container, a sibling of the whole app. So everything about it is reached\n * through the document root, scoped by the `aria-controls` id the trigger\n * publishes while the dialog is showing — which is what keeps two popconfirms\n * from reading each other's question, and why every panel reader throws while the\n * dialog is shut: there is no element to answer about.\n *\n * **The two actions are told apart by their own modifiers**, never by position.\n * `.wr-popconfirm__action--cancel` and `--confirm` are what `cancel()` and\n * `confirm()` click, so a template that ever reorders the pair cannot silently\n * turn a spec's \"cancel\" into a delete.\n *\n * Being a CONTENT CONTAINER means a consumer's own harnesses resolve INSIDE this\n * instance's panel — `popconfirm.getHarness(WrButtonHarness…)` reaches the\n * buttons without the spec ever naming the overlay.\n *\n * @example\n * ```ts\n * const loader = TestbedHarnessEnvironment.loader(fixture);\n * const remove = await loader.getHarness(WrPopconfirmHarness.with({ triggerText: 'Delete' }));\n *\n * await remove.open();\n * expect(await remove.getMessage()).toBe('Delete this item?');\n * await remove.confirm();\n * ```\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrPopconfirmHarness extends ContentContainerComponentHarness {\n /**\n * The directive's host — whatever element the consumer put `[wrPopconfirm]` on.\n *\n * Matched by the marker class, not by `[wrPopconfirm]`: the question is normally\n * BOUND (`[wrPopconfirm]=\"question\"`), and a property binding leaves no\n * attribute in the DOM at all. Same shape as `.wr-popover-trigger` and\n * `.wr-dropdown-trigger`.\n */\n static hostSelector = '.wr-popconfirm-trigger';\n\n /** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */\n static with(options: WrPopconfirmHarnessFilters = {}): HarnessPredicate<WrPopconfirmHarness> {\n return new HarnessPredicate(WrPopconfirmHarness, options)\n .addOption('triggerText', options.triggerText, (harness, text) =>\n HarnessPredicate.stringMatches(harness.getTriggerText(), text)\n )\n .addOption('open', options.open, async (harness, open) => (await harness.isOpen()) === open);\n }\n\n /** The trigger's own visible label. The question inside the panel is `getMessage()`. */\n async getTriggerText(): Promise<string> {\n return (await this.host()).text();\n }\n\n /**\n * Whether the dialog is showing.\n *\n * Read from `aria-expanded` rather than from a class, because that is the whole\n * of what the trigger tells a screen reader — the directive puts no state class\n * on its host at all.\n */\n async isOpen(): Promise<boolean> {\n return (await (await this.host()).getAttribute('aria-expanded')) === 'true';\n }\n\n /** Whether the trigger currently has keyboard focus — the state it is handed back on close. */\n async isTriggerFocused(): Promise<boolean> {\n return (await this.host()).isFocused();\n }\n\n /**\n * Press the trigger to open the dialog.\n *\n * Throws when nothing opens, because the reason is always worth failing on: a\n * native `<button disabled>` trigger never receives the click at all. (A\n * DISABLED `<wr-btn>` is a jsdom blind spot in the other direction — it is kept\n * inert by `pointer-events: none`, which jsdom does not apply, so it opens here\n * and would not in a browser.)\n */\n async open(): Promise<void> {\n if (await this.isOpen()) return;\n\n await (await this.host()).click();\n if (await this.isOpen()) return;\n\n throw new Error(\n 'WrPopconfirmHarness.open(): the dialog did not open. A disabled trigger takes no click — assert ' +\n 'the disabled state instead of trying to open it.'\n );\n }\n\n /**\n * Press the trigger again to take the question back.\n *\n * This is the ONE way out that answers nothing: the directive treats a second\n * press as withdrawing the question, so `cancelled` does NOT fire — unlike\n * `cancel()`, `sendEscape()` and `clickOutside()`, which all emit it. Use this\n * when a spec needs the panel gone without recording an answer.\n */\n async close(): Promise<void> {\n if (!(await this.isOpen())) return;\n\n await (await this.host()).click();\n if (!(await this.isOpen())) return;\n\n throw new Error('WrPopconfirmHarness.close(): the dialog is still open after a second press of the trigger.');\n }\n\n /** The question being asked. */\n async getMessage(): Promise<string> {\n return (await this.inPanel('.wr-popconfirm__message')).text();\n }\n\n /**\n * The confirm button's label.\n *\n * Resolved, not given: `confirmText` falls back to the `popconfirm.confirm`\n * catalog entry, so a localized app reads its own word here and a spec that\n * asserted the English default would be asserting the wrong thing.\n */\n async getConfirmText(): Promise<string> {\n return (await this.action('confirm')).text();\n }\n\n /** The cancel button's label — `cancelText`, or the `popconfirm.cancel` catalog entry. */\n async getCancelText(): Promise<string> {\n return (await this.action('cancel')).text();\n }\n\n /**\n * Both action labels in the order they are rendered: cancel first, confirm\n * second.\n *\n * That order is deliberate and worth reading — the destructive choice is the one\n * being confirmed, so the safe one comes first and takes the initial focus.\n */\n async getActionLabels(): Promise<string[]> {\n const actions = await this.allInPanel('.wr-popconfirm__action');\n return Promise.all(actions.map(action => action.text()));\n }\n\n /**\n * The confirm button's intent colour.\n *\n * Checked against `WR_COLORS` rather than pattern-matched out of the class list:\n * `wr-btn--*` also spells the size, the shape and the icon position, so only the\n * intent list can say which of them is a colour. Today `WrButton` happens to\n * emit the colour first, so a first-match regex would agree — but that order is\n * not a contract, and the same regex on a button with no colour answers `sm`.\n * Never `null` in practice — `confirmColor` defaults to `primary` — but typed\n * for it, since the button itself allows no colour at all.\n */\n async getConfirmColor(): Promise<WrColor | null> {\n const classes = (await (await this.action('confirm')).getAttribute('class')) ?? '';\n const present = classes.split(/\\s+/);\n return WR_COLORS.find(color => present.includes(`wr-btn--${color}`)) ?? null;\n }\n\n /** Which action holds keyboard focus, by label, or `null` when focus is elsewhere. */\n async getFocusedActionLabel(): Promise<string | null> {\n for (const action of await this.allInPanel('.wr-popconfirm__action')) {\n if (await action.isFocused()) return action.text();\n }\n return null;\n }\n\n /** Answer the question: click confirm, which emits `confirmed` and closes the dialog. */\n async confirm(): Promise<void> {\n return (await this.action('confirm')).click();\n }\n\n /** Decline: click cancel, which emits `cancelled` and closes the dialog. */\n async cancel(): Promise<void> {\n return (await this.action('cancel')).click();\n }\n\n /**\n * Dismiss with Escape, which emits `cancelled`.\n *\n * Sent at the pane rather than at the focused button, because the target makes\n * no difference: the key is picked up by the overlay's keyboard dispatcher,\n * which keeps one listener on the document and routes to the topmost overlay.\n * The pane is the one element guaranteed to be there.\n */\n async sendEscape(): Promise<void> {\n return (await this.pane()).sendKeys(TestKey.ESCAPE);\n }\n\n /**\n * Dismiss by pressing outside the panel, which emits `cancelled`.\n *\n * The press lands on the overlay CONTAINER — an ancestor of the pane (the CDK\n * puts a host `<div>` between the two), and so outside the panel by the only\n * measure that matters here, since the dismissal is decided by whether the press\n * started inside the pane. With two dialogs showing it dismisses BOTH: neither\n * pane contains the container. jsdom has no layout\n * and no `document.elementFromPoint`, so a harness cannot aim at \"whatever is\n * under the pointer\"; to dismiss by pressing a specific element instead, click\n * that element's own `TestElement`.\n */\n async clickOutside(): Promise<void> {\n const id = await this.panelId();\n const container = await this.documentRootLocatorFactory().locatorFor('.cdk-overlay-container')();\n\n await container.click();\n if (!(await this.isOpen())) return;\n\n throw new Error(\n `WrPopconfirmHarness.clickOutside(): the dialog (#${id}) is still open. An outside press is judged ` +\n 'by where it started, so a press that began inside the panel does not dismiss it.'\n );\n }\n\n /**\n * The role the open panel announces — `'dialog'`.\n *\n * Worth asserting rather than assuming: the directive sets it on the OVERLAY\n * PANE, not on the panel component a consumer can see in the template.\n */\n async getRole(): Promise<string | null> {\n return (await this.pane()).getAttribute('role');\n }\n\n /**\n * The dialog's accessible name — the `ariaLabel` input, or the catalog's\n * `popconfirm.label`.\n *\n * A `role=\"dialog\"` with no name announces as a bare \"dialog\" and trips axe's\n * `aria-dialog-name`, which is why there is always one.\n */\n async getLabel(): Promise<string | null> {\n return (await this.pane()).getAttribute('aria-label');\n }\n\n /**\n * Whether the dialog claims modality.\n *\n * `false`, deliberately, and worth pinning: focus is moved into the panel but\n * NOT trapped, because Escape and an outside click both dismiss — trapping\n * would only make it harder to leave.\n */\n async isModal(): Promise<boolean> {\n return (await (await this.pane()).getAttribute('aria-modal')) === 'true';\n }\n\n /**\n * The text a screen reader reads as the dialog's DESCRIPTION, resolved through\n * `aria-describedby` the way an assistive technology would.\n *\n * This is the question, and it is the entire content of a confirmation: without\n * the link the dialog announces its name and then nothing at all.\n */\n async getDescriptionText(): Promise<string | null> {\n const id = await (await this.pane()).getAttribute('aria-describedby');\n if (!id) return null;\n\n const described = await this.documentRootLocatorFactory().locatorForOptional(`#${id}`)();\n return described ? described.text() : null;\n }\n\n /**\n * Which side of the trigger the panel is anchored to.\n *\n * The side that was ASKED for, read off the pane's public modifier class —\n * `position` is an input, so a bound one never reaches the DOM, and the panel's\n * own offset is a CDK inline style that says nothing in a layout-less jsdom.\n * Not where the panel ended up: the position strategy is flexible and pushes,\n * so a panel with no room on that side moves without the class changing.\n */\n async getPosition(): Promise<WrPopconfirmPosition | null> {\n const classes = (await (await this.pane()).getAttribute('class')) ?? '';\n const modifier = /wr-popconfirm-overlay--([a-z]+)/.exec(classes);\n return modifier ? (modifier[1] as WrPopconfirmPosition) : null;\n }\n\n /**\n * Harnesses for anything inside the panel resolve within THIS instance's dialog.\n *\n * Scoped by the published id rather than by `.wr-popconfirm`: the overlay\n * container is shared, so a class query would answer with whichever popconfirm\n * opened first.\n */\n protected override async getRootHarnessLoader(): Promise<HarnessLoader> {\n return this.documentRootLocatorFactory().harnessLoaderFor(`#${await this.panelId()}`);\n }\n\n /**\n * One of the two action buttons.\n *\n * By its own modifier class, never by index: both are a `<wr-btn size=\"sm\">`, so\n * before the modifiers existed the only thing telling them apart was document\n * order — and a harness that clicked \"the second button\" would go on passing\n * while it started confirming what a spec meant to cancel.\n */\n private async action(role: WrPopconfirmAction): Promise<TestElement> {\n return this.inPanel(`.wr-popconfirm__action--${role}`);\n }\n\n /** One element inside THIS instance's panel. */\n private async inPanel(selector: string): Promise<TestElement> {\n return this.documentRootLocatorFactory().locatorFor(`#${await this.panelId()} ${selector}`)();\n }\n\n /** Every matching element inside THIS instance's panel, in document order. */\n private async allInPanel(selector: string): Promise<TestElement[]> {\n return this.documentRootLocatorFactory().locatorForAll(`#${await this.panelId()} ${selector}`)();\n }\n\n /** This instance's overlay pane — the element carrying the dialog semantics. */\n private async pane(): Promise<TestElement> {\n return this.documentRootLocatorFactory().locatorFor(`#${await this.panelId()}`)();\n }\n\n /** The id the trigger publishes for its dialog, which exists only while the dialog does. */\n private async panelId(): Promise<string> {\n const id = await (await this.host()).getAttribute('aria-controls');\n\n if (!id) {\n throw new Error(\n 'WrPopconfirmHarness: nothing is showing. The trigger publishes its dialog id as aria-controls ' +\n 'only while the dialog is open — call open() first.'\n );\n }\n return id;\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-popconfirm-testing.mjs","sources":["../../../projects/lib/popconfirm/testing/wr-popconfirm-harness.ts","../../../projects/lib/popconfirm/testing/ngwr-popconfirm-testing.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 {\n ContentContainerComponentHarness,\n type HarnessLoader,\n HarnessPredicate,\n TestKey,\n type TestElement,\n} from '@angular/cdk/testing';\n\nimport type { WrPopconfirmPosition } from 'ngwr/popconfirm';\nimport { WR_COLORS, type WrColor } from 'ngwr/theme';\n\nimport type { WrPopconfirmHarnessFilters } from './interfaces';\n\n/** The two answers a popconfirm offers, which are also its two action modifiers. */\ntype WrPopconfirmAction = 'confirm' | 'cancel';\n\n/**\n * Test harness for `[wrPopconfirm]` — the \"are you sure?\" dialog anchored to its\n * trigger.\n *\n * The panel is NOT inside the trigger: it is a component portal in the overlay\n * container, a sibling of the whole app. So everything about it is reached\n * through the document root, scoped by the `aria-controls` id the trigger\n * publishes while the dialog is showing — which is what keeps two popconfirms\n * from reading each other's question, and why every panel reader throws while the\n * dialog is shut: there is no element to answer about.\n *\n * **The two actions are told apart by their own modifiers**, never by position.\n * `.wr-popconfirm__action--cancel` and `--confirm` are what `cancel()` and\n * `confirm()` click, so a template that ever reorders the pair cannot silently\n * turn a spec's \"cancel\" into a delete.\n *\n * Being a CONTENT CONTAINER means a consumer's own harnesses resolve INSIDE this\n * instance's panel — `popconfirm.getHarness(WrButtonHarness…)` reaches the\n * buttons without the spec ever naming the overlay.\n *\n * @example\n * ```ts\n * const loader = TestbedHarnessEnvironment.loader(fixture);\n * const remove = await loader.getHarness(WrPopconfirmHarness.with({ triggerText: 'Delete' }));\n *\n * await remove.open();\n * expect(await remove.getMessage()).toBe('Delete this item?');\n * await remove.confirm();\n * ```\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrPopconfirmHarness extends ContentContainerComponentHarness {\n /**\n * The directive's host — whatever element the consumer put `[wrPopconfirm]` on.\n *\n * Matched by the marker class, not by `[wrPopconfirm]`: the question is normally\n * BOUND (`[wrPopconfirm]=\"question\"`), and a property binding leaves no\n * attribute in the DOM at all. Same shape as `.wr-popover-trigger` and\n * `.wr-dropdown-trigger`.\n */\n static hostSelector = '.wr-popconfirm-trigger';\n\n /** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */\n static with(options: WrPopconfirmHarnessFilters = {}): HarnessPredicate<WrPopconfirmHarness> {\n return new HarnessPredicate(WrPopconfirmHarness, options)\n .addOption('triggerText', options.triggerText, (harness, text) =>\n HarnessPredicate.stringMatches(harness.getTriggerText(), text)\n )\n .addOption('open', options.open, async (harness, open) => (await harness.isOpen()) === open);\n }\n\n /** The trigger's own visible label. The question inside the panel is `getMessage()`. */\n async getTriggerText(): Promise<string> {\n return (await this.host()).text();\n }\n\n /**\n * Whether the dialog is showing.\n *\n * Read from `aria-expanded` rather than from a class, because that is the whole\n * of what the trigger tells a screen reader — the directive puts no state class\n * on its host at all.\n */\n async isOpen(): Promise<boolean> {\n return (await (await this.host()).getAttribute('aria-expanded')) === 'true';\n }\n\n /** Whether the trigger currently has keyboard focus — the state it is handed back on close. */\n async isTriggerFocused(): Promise<boolean> {\n return (await this.host()).isFocused();\n }\n\n /**\n * Press the trigger to open the dialog.\n *\n * Throws when nothing opens, because the reason is always worth failing on: a\n * native `<button disabled>` trigger never receives the click at all. (A\n * DISABLED `<wr-btn>` is a jsdom blind spot in the other direction — it is kept\n * inert by `pointer-events: none`, which jsdom does not apply, so it opens here\n * and would not in a browser.)\n */\n async open(): Promise<void> {\n if (await this.isOpen()) return;\n\n await (await this.host()).click();\n if (await this.isOpen()) return;\n\n throw new Error(\n 'WrPopconfirmHarness.open(): the dialog did not open. A disabled trigger takes no click — assert ' +\n 'the disabled state instead of trying to open it.'\n );\n }\n\n /**\n * Press the trigger again to take the question back.\n *\n * This is the ONE way out that answers nothing: the directive treats a second\n * press as withdrawing the question, so `cancelled` does NOT fire — unlike\n * `cancel()`, `sendEscape()` and `clickOutside()`, which all emit it. Use this\n * when a spec needs the panel gone without recording an answer.\n */\n async close(): Promise<void> {\n if (!(await this.isOpen())) return;\n\n await (await this.host()).click();\n if (!(await this.isOpen())) return;\n\n throw new Error('WrPopconfirmHarness.close(): the dialog is still open after a second press of the trigger.');\n }\n\n /** The question being asked. */\n async getMessage(): Promise<string> {\n return (await this.inPanel('.wr-popconfirm__message')).text();\n }\n\n /**\n * The confirm button's label.\n *\n * Resolved, not given: `confirmText` falls back to the `popconfirm.confirm`\n * catalog entry, so a localized app reads its own word here and a spec that\n * asserted the English default would be asserting the wrong thing.\n */\n async getConfirmText(): Promise<string> {\n return (await this.action('confirm')).text();\n }\n\n /** The cancel button's label — `cancelText`, or the `popconfirm.cancel` catalog entry. */\n async getCancelText(): Promise<string> {\n return (await this.action('cancel')).text();\n }\n\n /**\n * Both action labels in the order they are rendered: cancel first, confirm\n * second.\n *\n * That order is deliberate and worth reading — the destructive choice is the one\n * being confirmed, so the safe one comes first and takes the initial focus.\n */\n async getActionLabels(): Promise<string[]> {\n const actions = await this.allInPanel('.wr-popconfirm__action');\n return Promise.all(actions.map(action => action.text()));\n }\n\n /**\n * The confirm button's intent colour.\n *\n * Checked against `WR_COLORS` rather than pattern-matched out of the class list:\n * `wr-btn--*` also spells the size, the shape and the icon position, so only the\n * intent list can say which of them is a colour. Today `WrButton` happens to\n * emit the colour first, so a first-match regex would agree — but that order is\n * not a contract, and the same regex on a button with no colour answers `sm`.\n * Never `null` in practice — `confirmColor` defaults to `primary` — but typed\n * for it, since the button itself allows no colour at all.\n */\n async getConfirmColor(): Promise<WrColor | null> {\n const classes = (await (await this.action('confirm')).getAttribute('class')) ?? '';\n const present = classes.split(/\\s+/);\n return WR_COLORS.find(color => present.includes(`wr-btn--${color}`)) ?? null;\n }\n\n /** Which action holds keyboard focus, by label, or `null` when focus is elsewhere. */\n async getFocusedActionLabel(): Promise<string | null> {\n for (const action of await this.allInPanel('.wr-popconfirm__action')) {\n if (await action.isFocused()) return action.text();\n }\n return null;\n }\n\n /** Answer the question: click confirm, which emits `confirmed` and closes the dialog. */\n async confirm(): Promise<void> {\n return (await this.action('confirm')).click();\n }\n\n /** Decline: click cancel, which emits `cancelled` and closes the dialog. */\n async cancel(): Promise<void> {\n return (await this.action('cancel')).click();\n }\n\n /**\n * Dismiss with Escape, which emits `cancelled`.\n *\n * Sent at the pane rather than at the focused button, because the target makes\n * no difference: the key is picked up by the overlay's keyboard dispatcher,\n * which keeps one listener on the document and routes to the topmost overlay.\n * The pane is the one element guaranteed to be there.\n */\n async sendEscape(): Promise<void> {\n return (await this.pane()).sendKeys(TestKey.ESCAPE);\n }\n\n /**\n * Dismiss by pressing outside the panel, which emits `cancelled`.\n *\n * The press lands on the overlay CONTAINER — an ancestor of the pane (the CDK\n * puts a host `<div>` between the two), and so outside the panel by the only\n * measure that matters here, since the dismissal is decided by whether the press\n * started inside the pane. With two dialogs showing it dismisses BOTH: neither\n * pane contains the container. jsdom has no layout\n * and no `document.elementFromPoint`, so a harness cannot aim at \"whatever is\n * under the pointer\"; to dismiss by pressing a specific element instead, click\n * that element's own `TestElement`.\n */\n async clickOutside(): Promise<void> {\n const id = await this.panelId();\n const container = await this.documentRootLocatorFactory().locatorFor('.cdk-overlay-container')();\n\n await container.click();\n if (!(await this.isOpen())) return;\n\n throw new Error(\n `WrPopconfirmHarness.clickOutside(): the dialog (#${id}) is still open. An outside press is judged ` +\n 'by where it started, so a press that began inside the panel does not dismiss it.'\n );\n }\n\n /**\n * The role the open panel announces — `'dialog'`.\n *\n * Worth asserting rather than assuming: the directive sets it on the OVERLAY\n * PANE, not on the panel component a consumer can see in the template.\n */\n async getRole(): Promise<string | null> {\n return (await this.pane()).getAttribute('role');\n }\n\n /**\n * The dialog's accessible name — the `ariaLabel` input, or the catalog's\n * `popconfirm.label`.\n *\n * A `role=\"dialog\"` with no name announces as a bare \"dialog\" and trips axe's\n * `aria-dialog-name`, which is why there is always one.\n */\n async getLabel(): Promise<string | null> {\n return (await this.pane()).getAttribute('aria-label');\n }\n\n /**\n * Whether the dialog claims modality.\n *\n * `false`, deliberately, and worth pinning: focus is moved into the panel but\n * NOT trapped, because Escape and an outside click both dismiss — trapping\n * would only make it harder to leave.\n */\n async isModal(): Promise<boolean> {\n return (await (await this.pane()).getAttribute('aria-modal')) === 'true';\n }\n\n /**\n * The text a screen reader reads as the dialog's DESCRIPTION, resolved through\n * `aria-describedby` the way an assistive technology would.\n *\n * This is the question, and it is the entire content of a confirmation: without\n * the link the dialog announces its name and then nothing at all.\n */\n async getDescriptionText(): Promise<string | null> {\n const id = await (await this.pane()).getAttribute('aria-describedby');\n if (!id) return null;\n\n const described = await this.documentRootLocatorFactory().locatorForOptional(`#${id}`)();\n return described ? described.text() : null;\n }\n\n /**\n * Which side of the trigger the panel is anchored to.\n *\n * The side that was ASKED for, read off the pane's public modifier class —\n * `position` is an input, so a bound one never reaches the DOM, and the panel's\n * own offset is a CDK inline style that says nothing in a layout-less jsdom.\n * Not where the panel ended up: the position strategy is flexible and pushes,\n * so a panel with no room on that side moves without the class changing.\n */\n async getPosition(): Promise<WrPopconfirmPosition | null> {\n const classes = (await (await this.pane()).getAttribute('class')) ?? '';\n const modifier = /wr-popconfirm-overlay--([a-z]+)/.exec(classes);\n return modifier ? (modifier[1] as WrPopconfirmPosition) : null;\n }\n\n /**\n * Harnesses for anything inside the panel resolve within THIS instance's dialog.\n *\n * Scoped by the published id rather than by `.wr-popconfirm`: the overlay\n * container is shared, so a class query would answer with whichever popconfirm\n * opened first.\n */\n protected override async getRootHarnessLoader(): Promise<HarnessLoader> {\n return this.documentRootLocatorFactory().harnessLoaderFor(`#${await this.panelId()}`);\n }\n\n /**\n * One of the two action buttons.\n *\n * By its own modifier class, never by index: both are a `<wr-btn size=\"sm\">`, so\n * before the modifiers existed the only thing telling them apart was document\n * order — and a harness that clicked \"the second button\" would go on passing\n * while it started confirming what a spec meant to cancel.\n */\n private async action(role: WrPopconfirmAction): Promise<TestElement> {\n return this.inPanel(`.wr-popconfirm__action--${role}`);\n }\n\n /** One element inside THIS instance's panel. */\n private async inPanel(selector: string): Promise<TestElement> {\n return this.documentRootLocatorFactory().locatorFor(`#${await this.panelId()} ${selector}`)();\n }\n\n /** Every matching element inside THIS instance's panel, in document order. */\n private async allInPanel(selector: string): Promise<TestElement[]> {\n return this.documentRootLocatorFactory().locatorForAll(`#${await this.panelId()} ${selector}`)();\n }\n\n /** This instance's overlay pane — the element carrying the dialog semantics. */\n private async pane(): Promise<TestElement> {\n return this.documentRootLocatorFactory().locatorFor(`#${await this.panelId()}`)();\n }\n\n /** The id the trigger publishes for its dialog, which exists only while the dialog does. */\n private async panelId(): Promise<string> {\n const id = await (await this.host()).getAttribute('aria-controls');\n\n if (!id) {\n throw new Error(\n 'WrPopconfirmHarness: nothing is showing. The trigger publishes its dialog id as aria-controls ' +\n 'only while the dialog is open — call open() first.'\n );\n }\n return id;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -48,10 +48,10 @@ class WrPopconfirmPanel {
48
48
  ...(ngDevMode ? [{ debugName: "confirmColor" }] : /* istanbul ignore next */ []));
49
49
  confirmed = output();
50
50
  cancelled = output();
51
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrPopconfirmPanel, deps: [], target: i0.ɵɵFactoryTarget.Component });
52
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: WrPopconfirmPanel, isStandalone: true, selector: "wr-popconfirm", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: true, transformFunction: null }, messageId: { classPropertyName: "messageId", publicName: "messageId", isSignal: true, isRequired: false, transformFunction: null }, confirmText: { classPropertyName: "confirmText", publicName: "confirmText", isSignal: true, isRequired: false, transformFunction: null }, cancelText: { classPropertyName: "cancelText", publicName: "cancelText", isSignal: true, isRequired: false, transformFunction: null }, confirmColor: { classPropertyName: "confirmColor", publicName: "confirmColor", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { confirmed: "confirmed", cancelled: "cancelled" }, host: { classAttribute: "wr-popconfirm" }, ngImport: i0, template: "<p class=\"wr-popconfirm__message\" [attr.id]=\"messageId()\">{{ message() }}</p>\n\n<div class=\"wr-popconfirm__actions\">\n <wr-btn class=\"wr-popconfirm__action wr-popconfirm__action--cancel\" size=\"sm\" (click)=\"cancelled.emit()\">\n {{ cancelText() }}\n </wr-btn>\n <wr-btn\n class=\"wr-popconfirm__action wr-popconfirm__action--confirm\"\n size=\"sm\"\n [color]=\"confirmColor()\"\n (click)=\"confirmed.emit()\"\n >\n {{ confirmText() }}\n </wr-btn>\n</div>\n", dependencies: [{ kind: "component", type: WrButton, selector: "wr-btn, button[wr-btn], a[wr-btn]", inputs: ["color", "size", "shape", "icon", "iconPosition", "disabled", "outlined", "block", "loading", "disabledWhenLoading"] }], encapsulation: i0.ViewEncapsulation.None });
51
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrPopconfirmPanel, deps: [], target: i0.ɵɵFactoryTarget.Component });
52
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.7", type: WrPopconfirmPanel, isStandalone: true, selector: "wr-popconfirm", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: true, transformFunction: null }, messageId: { classPropertyName: "messageId", publicName: "messageId", isSignal: true, isRequired: false, transformFunction: null }, confirmText: { classPropertyName: "confirmText", publicName: "confirmText", isSignal: true, isRequired: false, transformFunction: null }, cancelText: { classPropertyName: "cancelText", publicName: "cancelText", isSignal: true, isRequired: false, transformFunction: null }, confirmColor: { classPropertyName: "confirmColor", publicName: "confirmColor", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { confirmed: "confirmed", cancelled: "cancelled" }, host: { classAttribute: "wr-popconfirm" }, ngImport: i0, template: "<p class=\"wr-popconfirm__message\" [attr.id]=\"messageId()\">{{ message() }}</p>\n\n<div class=\"wr-popconfirm__actions\">\n <wr-btn class=\"wr-popconfirm__action wr-popconfirm__action--cancel\" size=\"sm\" (click)=\"cancelled.emit()\">\n {{ cancelText() }}\n </wr-btn>\n <wr-btn\n class=\"wr-popconfirm__action wr-popconfirm__action--confirm\"\n size=\"sm\"\n [color]=\"confirmColor()\"\n (click)=\"confirmed.emit()\"\n >\n {{ confirmText() }}\n </wr-btn>\n</div>\n", dependencies: [{ kind: "component", type: WrButton, selector: "wr-btn, button[wr-btn], a[wr-btn]", inputs: ["color", "size", "shape", "icon", "iconPosition", "disabled", "outlined", "block", "loading", "disabledWhenLoading"] }], encapsulation: i0.ViewEncapsulation.None });
53
53
  }
54
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrPopconfirmPanel, decorators: [{
54
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrPopconfirmPanel, decorators: [{
55
55
  type: Component,
56
56
  args: [{ selector: 'wr-popconfirm', encapsulation: ViewEncapsulation.None, host: { class: 'wr-popconfirm' }, imports: [WrButton], template: "<p class=\"wr-popconfirm__message\" [attr.id]=\"messageId()\">{{ message() }}</p>\n\n<div class=\"wr-popconfirm__actions\">\n <wr-btn class=\"wr-popconfirm__action wr-popconfirm__action--cancel\" size=\"sm\" (click)=\"cancelled.emit()\">\n {{ cancelText() }}\n </wr-btn>\n <wr-btn\n class=\"wr-popconfirm__action wr-popconfirm__action--confirm\"\n size=\"sm\"\n [color]=\"confirmColor()\"\n (click)=\"confirmed.emit()\"\n >\n {{ confirmText() }}\n </wr-btn>\n</div>\n" }]
57
57
  }], propDecorators: { message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: true }] }], messageId: [{ type: i0.Input, args: [{ isSignal: true, alias: "messageId", required: false }] }], confirmText: [{ type: i0.Input, args: [{ isSignal: true, alias: "confirmText", required: false }] }], cancelText: [{ type: i0.Input, args: [{ isSignal: true, alias: "cancelText", required: false }] }], confirmColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "confirmColor", required: false }] }], confirmed: [{ type: i0.Output, args: ["confirmed"] }], cancelled: [{ type: i0.Output, args: ["cancelled"] }] } });
@@ -251,10 +251,10 @@ class WrPopconfirm {
251
251
  isRtl() {
252
252
  return this.dir?.value === 'rtl';
253
253
  }
254
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrPopconfirm, deps: [], target: i0.ɵɵFactoryTarget.Directive });
255
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.6", type: WrPopconfirm, isStandalone: true, selector: "[wrPopconfirm]", inputs: { message: { classPropertyName: "message", publicName: "wrPopconfirm", isSignal: true, isRequired: true, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, confirmText: { classPropertyName: "confirmText", publicName: "confirmText", isSignal: true, isRequired: false, transformFunction: null }, cancelText: { classPropertyName: "cancelText", publicName: "cancelText", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, confirmColor: { classPropertyName: "confirmColor", publicName: "confirmColor", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { confirmed: "confirmed", cancelled: "cancelled" }, host: { listeners: { "click": "toggle($event)" }, properties: { "attr.aria-haspopup": "\"dialog\"", "attr.aria-expanded": "isOpen()", "attr.aria-controls": "isOpen() ? panelId : null" }, classAttribute: "wr-popconfirm-trigger" }, exportAs: ["wrPopconfirm"], ngImport: i0 });
254
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrPopconfirm, deps: [], target: i0.ɵɵFactoryTarget.Directive });
255
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.7", type: WrPopconfirm, isStandalone: true, selector: "[wrPopconfirm]", inputs: { message: { classPropertyName: "message", publicName: "wrPopconfirm", isSignal: true, isRequired: true, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, confirmText: { classPropertyName: "confirmText", publicName: "confirmText", isSignal: true, isRequired: false, transformFunction: null }, cancelText: { classPropertyName: "cancelText", publicName: "cancelText", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, confirmColor: { classPropertyName: "confirmColor", publicName: "confirmColor", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { confirmed: "confirmed", cancelled: "cancelled" }, host: { listeners: { "click": "toggle($event)" }, properties: { "attr.aria-haspopup": "\"dialog\"", "attr.aria-expanded": "isOpen()", "attr.aria-controls": "isOpen() ? panelId : null" }, classAttribute: "wr-popconfirm-trigger" }, exportAs: ["wrPopconfirm"], ngImport: i0 });
256
256
  }
257
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrPopconfirm, decorators: [{
257
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrPopconfirm, decorators: [{
258
258
  type: Directive,
259
259
  args: [{
260
260
  selector: '[wrPopconfirm]',
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-popconfirm.mjs","sources":["../../../projects/lib/popconfirm/interfaces/popconfirm-position.ts","../../../projects/lib/popconfirm/popconfirm-panel.ts","../../../projects/lib/popconfirm/popconfirm-panel.html","../../../projects/lib/popconfirm/popconfirm.ts","../../../projects/lib/popconfirm/ngwr-popconfirm.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 { ConnectedPosition } from '@angular/cdk/overlay';\n\nexport type WrPopconfirmPosition = 'top' | 'bottom' | 'left' | 'right';\n\n/** @internal */\nexport const WR_POPCONFIRM_POSITIONS: Record<WrPopconfirmPosition, ConnectedPosition[]> = {\n top: [{ originX: 'center', originY: 'top', overlayX: 'center', overlayY: 'bottom', offsetY: -8 }],\n bottom: [{ originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top', offsetY: 8 }],\n left: [{ originX: 'start', originY: 'center', overlayX: 'end', overlayY: 'center', offsetX: -8 }],\n right: [{ originX: 'end', originY: 'center', overlayX: 'start', overlayY: 'center', offsetX: 8 }],\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 { Component, ViewEncapsulation, input, output } from '@angular/core';\n\nimport { WrButton } from 'ngwr/button';\nimport type { WrColor } from 'ngwr/theme';\n\n/**\n * Confirmation panel rendered inside the popconfirm overlay. Not part\n * of the public template API — use `[wrPopconfirm]` instead.\n *\n * @internal\n */\n@Component({\n selector: 'wr-popconfirm',\n templateUrl: './popconfirm-panel.html',\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-popconfirm' },\n imports: [WrButton],\n})\nexport class WrPopconfirmPanel {\n readonly message = input.required<string>();\n\n /** Id the anchoring directive points `aria-describedby` at. */\n readonly messageId = input<string | null>(null);\n readonly confirmText = input<string>('Confirm');\n readonly cancelText = input<string>('Cancel');\n readonly confirmColor = input<WrColor>('primary');\n\n readonly confirmed = output<void>();\n readonly cancelled = output<void>();\n}\n","<p class=\"wr-popconfirm__message\" [attr.id]=\"messageId()\">{{ message() }}</p>\n\n<div class=\"wr-popconfirm__actions\">\n <wr-btn class=\"wr-popconfirm__action wr-popconfirm__action--cancel\" size=\"sm\" (click)=\"cancelled.emit()\">\n {{ cancelText() }}\n </wr-btn>\n <wr-btn\n class=\"wr-popconfirm__action wr-popconfirm__action--confirm\"\n size=\"sm\"\n [color]=\"confirmColor()\"\n (click)=\"confirmed.emit()\"\n >\n {{ confirmText() }}\n </wr-btn>\n</div>\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 { Directionality } from '@angular/cdk/bidi';\nimport { type OverlayRef, ScrollStrategyOptions } from '@angular/cdk/overlay';\nimport { ComponentPortal } from '@angular/cdk/portal';\nimport {\n DestroyRef,\n Directive,\n ElementRef,\n Injector,\n ViewContainerRef,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport { useI18nText } from 'ngwr/i18n';\nimport { WR_OVERLAY, WrOutsideClick, wrFollowDirection, wrMirrorOffsets } from 'ngwr/overlay';\nimport type { WrColor } from 'ngwr/theme';\n\nimport { WR_POPCONFIRM_POSITIONS, type WrPopconfirmPosition } from './interfaces';\nimport { WrPopconfirmPanel } from './popconfirm-panel';\n\n/**\n * Small \"Are you sure?\" panel anchored to its trigger. Fires `confirmed`\n * or `cancelled` and closes automatically. Built on CDK Overlay.\n *\n * @example\n * ```html\n * <wr-btn\n * color=\"danger\"\n * [wrPopconfirm]=\"'Delete this item?'\"\n * confirmColor=\"danger\"\n * confirmText=\"Delete\"\n * (confirmed)=\"remove()\"\n * >Delete</wr-btn>\n * ```\n *\n * @see https://ngwr.dev/reference/components/popconfirm\n */\nlet popconfirmUid = 0;\n\n@Directive({\n selector: '[wrPopconfirm]',\n exportAs: 'wrPopconfirm',\n host: {\n // Marks the trigger the way `[wrPopover]` and `[wrDropdown]` mark theirs. The\n // question is normally BOUND (`[wrPopconfirm]=\"question\"`), which leaves no\n // attribute in the DOM at all, so without this there is nothing to find a\n // trigger by once the panel is shut.\n class: 'wr-popconfirm-trigger',\n '(click)': 'toggle($event)',\n '[attr.aria-haspopup]': '\"dialog\"',\n '[attr.aria-expanded]': 'isOpen()',\n // Names the dialog this trigger opened, as every other overlay trigger in the\n // catalog does. `aria-haspopup=\"dialog\"` promises a dialog and `aria-expanded`\n // says it is showing; without the id, which one is left to guess.\n '[attr.aria-controls]': 'isOpen() ? panelId : null',\n },\n})\nexport class WrPopconfirm {\n /** Confirmation message. */\n readonly message = input.required<string>({ alias: 'wrPopconfirm' });\n\n /** Anchor side. @default 'top' */\n readonly position = input<WrPopconfirmPosition>('top');\n\n /** Label for the confirm button. @default 'Confirm' */\n /** Confirm button text. Falls back to `popconfirm.confirm`. */\n readonly confirmText = input<string | null>(null);\n\n /** Label for the cancel button. @default 'Cancel' */\n /** Cancel button text. Falls back to `popconfirm.cancel`. */\n readonly cancelText = input<string | null>(null);\n\n /**\n * Accessible name of the confirmation dialog. `role=\"dialog\"` with no name\n * announces as a bare \"dialog\". Falls back to `popconfirm.label`.\n */\n readonly ariaLabel = input<string | null>(null);\n\n // The catalog has carried these translated for as long as the component has\n // existed; the labels were hard-coded English defaults, so a localized app got\n // English buttons with the right strings sitting one file away.\n private readonly resolvedConfirm = useI18nText(this.confirmText, 'popconfirm.confirm', 'Confirm');\n private readonly resolvedCancel = useI18nText(this.cancelText, 'popconfirm.cancel', 'Cancel');\n private readonly resolvedAriaLabel = useI18nText(this.ariaLabel, 'popconfirm.label', 'Confirm action');\n\n /** Color of the confirm button. @default 'primary' */\n readonly confirmColor = input<WrColor>('primary');\n\n /** Fires when the user clicks confirm. */\n readonly confirmed = output<void>();\n\n /** Fires when the user clicks cancel or dismisses the overlay. */\n readonly cancelled = output<void>();\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly overlay = inject(WR_OVERLAY);\n private readonly dir = inject(Directionality, { optional: true });\n private readonly outsideClick = inject(WrOutsideClick);\n private readonly vcr = inject(ViewContainerRef);\n private readonly scrollStrategies = inject(ScrollStrategyOptions);\n private readonly injector = inject(Injector);\n private readonly destroyRef = inject(DestroyRef);\n\n /** @internal Public so the host bindings can read it. */\n readonly isOpen = signal(false);\n\n private overlayRef: OverlayRef | null = null;\n\n private readonly uid = ++popconfirmUid;\n\n /** @internal Public so the host binding can read it. */\n protected readonly panelId = `wr-popconfirm-${this.uid}`;\n\n private readonly messageId = `wr-popconfirm-message-${this.uid}`;\n\n constructor() {\n this.destroyRef.onDestroy(() => this.dispose());\n }\n\n /** @internal */\n protected toggle(event: MouseEvent): void {\n event.stopPropagation();\n if (this.overlayRef) {\n this.close();\n } else {\n this.open();\n }\n }\n\n open(): void {\n if (this.overlayRef) return;\n\n // Read ONCE, here, and mirror this list rather than the input: the side is\n // chosen at open and a later `position` write moves nothing, so a follower\n // that re-read the signal would let a direction flip quietly adopt a\n // position the panel never opened with — and the `wr-popconfirm-overlay--…`\n // class minted from the same read below, which is what the stylesheet hangs\n // the arrow and the spacing off, would still name the old one.\n const positions = WR_POPCONFIRM_POSITIONS[this.position()];\n\n const positionStrategy = this.overlay\n .position()\n .flexibleConnectedTo(this.host)\n .withPositions(wrMirrorOffsets(positions, this.isRtl()))\n .withPush(true);\n\n this.overlayRef = this.overlay.create({\n positionStrategy,\n scrollStrategy: this.scrollStrategies.reposition(),\n panelClass: ['wr-popconfirm-overlay', `wr-popconfirm-overlay--${this.position()}`],\n });\n\n // `isRtl()` above answered once, at `create()`, and so did the CDK's own\n // capture of the direction — neither is revisited if the app flips while the\n // question is still on screen. Both halves have to move: the `dir` on the\n // host, so `start` / `end` resolve to the other edge, and the mirrored list,\n // because `offsetX` is added to the final PHYSICAL x. Leave the list behind\n // and the 8px gap on `left` / `right` becomes an 8px overlap over the very\n // control the panel is asking about.\n wrFollowDirection(this.overlayRef, this.dir, this.injector, direction =>\n positionStrategy.withPositions(wrMirrorOffsets(positions, direction === 'rtl'))\n );\n\n // Non-modal by choice, like `wr-popover`: an outside click or Escape closes it,\n // so trapping focus would only make it harder to leave. It still needs a role, a\n // name and the question read out as its description.\n const pane = this.overlayRef.overlayElement;\n pane.id = this.panelId;\n pane.setAttribute('role', 'dialog');\n pane.setAttribute('aria-modal', 'false');\n pane.setAttribute('aria-label', this.resolvedAriaLabel());\n pane.setAttribute('aria-describedby', this.messageId);\n\n const portal = new ComponentPortal(WrPopconfirmPanel, this.vcr);\n const ref = this.overlayRef.attach(portal);\n ref.setInput('message', this.message());\n ref.setInput('messageId', this.messageId);\n ref.setInput('confirmText', this.resolvedConfirm());\n ref.setInput('cancelText', this.resolvedCancel());\n ref.setInput('confirmColor', this.confirmColor());\n // Render now rather than next frame: the buttons have to exist before focus can\n // move to one, and a deferred focus is the class of bug this repo keeps finding.\n ref.changeDetectorRef.detectChanges();\n // Focus has to enter the panel — the overlay container sits at the end of\n // `<body>`, so Tab from the trigger went to the next thing on the PAGE and the\n // only way to confirm was unreachable. Cancel first: the action being confirmed\n // is usually the destructive one.\n pane.querySelector<HTMLElement>('.wr-popconfirm__actions wr-btn')?.focus();\n this.isOpen.set(true);\n\n ref.instance.confirmed.subscribe(() => {\n this.confirmed.emit();\n this.close();\n });\n ref.instance.cancelled.subscribe(() => this.dismiss());\n\n this.outsideClick\n .outsidePointerEvents(this.overlayRef)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(event => {\n if (this.host.nativeElement.contains(event.target as Node)) return;\n this.dismiss();\n });\n\n this.overlayRef\n .keydownEvents()\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(event => {\n if (event.key === 'Escape') {\n event.preventDefault();\n this.dismiss();\n }\n });\n }\n\n close(): void {\n this.dispose();\n }\n\n private dismiss(): void {\n if (!this.overlayRef) return;\n this.cancelled.emit();\n this.dispose();\n }\n\n private dispose(): void {\n if (!this.overlayRef) return;\n // Focus lives inside the panel while it is open, and removing the panel would\n // drop it to `<body>` — hand it back to the trigger instead, as `wr-dropdown`\n // does on Escape. Only when focus is still IN there: if the user has already\n // clicked elsewhere, taking it back would be stealing.\n const returnFocus = this.overlayRef.overlayElement.contains(document.activeElement);\n this.overlayRef.dispose();\n this.overlayRef = null;\n this.isOpen.set(false);\n if (returnFocus) this.host.nativeElement.focus();\n }\n\n /**\n * Whether the app reads right-to-left.\n *\n * Optional inject: `Directionality` is root-provided, so this is never null in\n * an app — but a bare `TestBed` that provides nothing should still get a\n * component that works, and defaulting to LTR is the honest fallback.\n */\n private isRtl(): boolean {\n return this.dir?.value === 'rtl';\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-popconfirm.mjs","sources":["../../../projects/lib/popconfirm/interfaces/popconfirm-position.ts","../../../projects/lib/popconfirm/popconfirm-panel.ts","../../../projects/lib/popconfirm/popconfirm-panel.html","../../../projects/lib/popconfirm/popconfirm.ts","../../../projects/lib/popconfirm/ngwr-popconfirm.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 { ConnectedPosition } from '@angular/cdk/overlay';\n\nexport type WrPopconfirmPosition = 'top' | 'bottom' | 'left' | 'right';\n\n/** @internal */\nexport const WR_POPCONFIRM_POSITIONS: Record<WrPopconfirmPosition, ConnectedPosition[]> = {\n top: [{ originX: 'center', originY: 'top', overlayX: 'center', overlayY: 'bottom', offsetY: -8 }],\n bottom: [{ originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top', offsetY: 8 }],\n left: [{ originX: 'start', originY: 'center', overlayX: 'end', overlayY: 'center', offsetX: -8 }],\n right: [{ originX: 'end', originY: 'center', overlayX: 'start', overlayY: 'center', offsetX: 8 }],\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 { Component, ViewEncapsulation, input, output } from '@angular/core';\n\nimport { WrButton } from 'ngwr/button';\nimport type { WrColor } from 'ngwr/theme';\n\n/**\n * Confirmation panel rendered inside the popconfirm overlay. Not part\n * of the public template API — use `[wrPopconfirm]` instead.\n *\n * @internal\n */\n@Component({\n selector: 'wr-popconfirm',\n templateUrl: './popconfirm-panel.html',\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-popconfirm' },\n imports: [WrButton],\n})\nexport class WrPopconfirmPanel {\n readonly message = input.required<string>();\n\n /** Id the anchoring directive points `aria-describedby` at. */\n readonly messageId = input<string | null>(null);\n readonly confirmText = input<string>('Confirm');\n readonly cancelText = input<string>('Cancel');\n readonly confirmColor = input<WrColor>('primary');\n\n readonly confirmed = output<void>();\n readonly cancelled = output<void>();\n}\n","<p class=\"wr-popconfirm__message\" [attr.id]=\"messageId()\">{{ message() }}</p>\n\n<div class=\"wr-popconfirm__actions\">\n <wr-btn class=\"wr-popconfirm__action wr-popconfirm__action--cancel\" size=\"sm\" (click)=\"cancelled.emit()\">\n {{ cancelText() }}\n </wr-btn>\n <wr-btn\n class=\"wr-popconfirm__action wr-popconfirm__action--confirm\"\n size=\"sm\"\n [color]=\"confirmColor()\"\n (click)=\"confirmed.emit()\"\n >\n {{ confirmText() }}\n </wr-btn>\n</div>\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 { Directionality } from '@angular/cdk/bidi';\nimport { type OverlayRef, ScrollStrategyOptions } from '@angular/cdk/overlay';\nimport { ComponentPortal } from '@angular/cdk/portal';\nimport {\n DestroyRef,\n Directive,\n ElementRef,\n Injector,\n ViewContainerRef,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport { useI18nText } from 'ngwr/i18n';\nimport { WR_OVERLAY, WrOutsideClick, wrFollowDirection, wrMirrorOffsets } from 'ngwr/overlay';\nimport type { WrColor } from 'ngwr/theme';\n\nimport { WR_POPCONFIRM_POSITIONS, type WrPopconfirmPosition } from './interfaces';\nimport { WrPopconfirmPanel } from './popconfirm-panel';\n\n/**\n * Small \"Are you sure?\" panel anchored to its trigger. Fires `confirmed`\n * or `cancelled` and closes automatically. Built on CDK Overlay.\n *\n * @example\n * ```html\n * <wr-btn\n * color=\"danger\"\n * [wrPopconfirm]=\"'Delete this item?'\"\n * confirmColor=\"danger\"\n * confirmText=\"Delete\"\n * (confirmed)=\"remove()\"\n * >Delete</wr-btn>\n * ```\n *\n * @see https://ngwr.dev/reference/components/popconfirm\n */\nlet popconfirmUid = 0;\n\n@Directive({\n selector: '[wrPopconfirm]',\n exportAs: 'wrPopconfirm',\n host: {\n // Marks the trigger the way `[wrPopover]` and `[wrDropdown]` mark theirs. The\n // question is normally BOUND (`[wrPopconfirm]=\"question\"`), which leaves no\n // attribute in the DOM at all, so without this there is nothing to find a\n // trigger by once the panel is shut.\n class: 'wr-popconfirm-trigger',\n '(click)': 'toggle($event)',\n '[attr.aria-haspopup]': '\"dialog\"',\n '[attr.aria-expanded]': 'isOpen()',\n // Names the dialog this trigger opened, as every other overlay trigger in the\n // catalog does. `aria-haspopup=\"dialog\"` promises a dialog and `aria-expanded`\n // says it is showing; without the id, which one is left to guess.\n '[attr.aria-controls]': 'isOpen() ? panelId : null',\n },\n})\nexport class WrPopconfirm {\n /** Confirmation message. */\n readonly message = input.required<string>({ alias: 'wrPopconfirm' });\n\n /** Anchor side. @default 'top' */\n readonly position = input<WrPopconfirmPosition>('top');\n\n /** Label for the confirm button. @default 'Confirm' */\n /** Confirm button text. Falls back to `popconfirm.confirm`. */\n readonly confirmText = input<string | null>(null);\n\n /** Label for the cancel button. @default 'Cancel' */\n /** Cancel button text. Falls back to `popconfirm.cancel`. */\n readonly cancelText = input<string | null>(null);\n\n /**\n * Accessible name of the confirmation dialog. `role=\"dialog\"` with no name\n * announces as a bare \"dialog\". Falls back to `popconfirm.label`.\n */\n readonly ariaLabel = input<string | null>(null);\n\n // The catalog has carried these translated for as long as the component has\n // existed; the labels were hard-coded English defaults, so a localized app got\n // English buttons with the right strings sitting one file away.\n private readonly resolvedConfirm = useI18nText(this.confirmText, 'popconfirm.confirm', 'Confirm');\n private readonly resolvedCancel = useI18nText(this.cancelText, 'popconfirm.cancel', 'Cancel');\n private readonly resolvedAriaLabel = useI18nText(this.ariaLabel, 'popconfirm.label', 'Confirm action');\n\n /** Color of the confirm button. @default 'primary' */\n readonly confirmColor = input<WrColor>('primary');\n\n /** Fires when the user clicks confirm. */\n readonly confirmed = output<void>();\n\n /** Fires when the user clicks cancel or dismisses the overlay. */\n readonly cancelled = output<void>();\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly overlay = inject(WR_OVERLAY);\n private readonly dir = inject(Directionality, { optional: true });\n private readonly outsideClick = inject(WrOutsideClick);\n private readonly vcr = inject(ViewContainerRef);\n private readonly scrollStrategies = inject(ScrollStrategyOptions);\n private readonly injector = inject(Injector);\n private readonly destroyRef = inject(DestroyRef);\n\n /** @internal Public so the host bindings can read it. */\n readonly isOpen = signal(false);\n\n private overlayRef: OverlayRef | null = null;\n\n private readonly uid = ++popconfirmUid;\n\n /** @internal Public so the host binding can read it. */\n protected readonly panelId = `wr-popconfirm-${this.uid}`;\n\n private readonly messageId = `wr-popconfirm-message-${this.uid}`;\n\n constructor() {\n this.destroyRef.onDestroy(() => this.dispose());\n }\n\n /** @internal */\n protected toggle(event: MouseEvent): void {\n event.stopPropagation();\n if (this.overlayRef) {\n this.close();\n } else {\n this.open();\n }\n }\n\n open(): void {\n if (this.overlayRef) return;\n\n // Read ONCE, here, and mirror this list rather than the input: the side is\n // chosen at open and a later `position` write moves nothing, so a follower\n // that re-read the signal would let a direction flip quietly adopt a\n // position the panel never opened with — and the `wr-popconfirm-overlay--…`\n // class minted from the same read below, which is what the stylesheet hangs\n // the arrow and the spacing off, would still name the old one.\n const positions = WR_POPCONFIRM_POSITIONS[this.position()];\n\n const positionStrategy = this.overlay\n .position()\n .flexibleConnectedTo(this.host)\n .withPositions(wrMirrorOffsets(positions, this.isRtl()))\n .withPush(true);\n\n this.overlayRef = this.overlay.create({\n positionStrategy,\n scrollStrategy: this.scrollStrategies.reposition(),\n panelClass: ['wr-popconfirm-overlay', `wr-popconfirm-overlay--${this.position()}`],\n });\n\n // `isRtl()` above answered once, at `create()`, and so did the CDK's own\n // capture of the direction — neither is revisited if the app flips while the\n // question is still on screen. Both halves have to move: the `dir` on the\n // host, so `start` / `end` resolve to the other edge, and the mirrored list,\n // because `offsetX` is added to the final PHYSICAL x. Leave the list behind\n // and the 8px gap on `left` / `right` becomes an 8px overlap over the very\n // control the panel is asking about.\n wrFollowDirection(this.overlayRef, this.dir, this.injector, direction =>\n positionStrategy.withPositions(wrMirrorOffsets(positions, direction === 'rtl'))\n );\n\n // Non-modal by choice, like `wr-popover`: an outside click or Escape closes it,\n // so trapping focus would only make it harder to leave. It still needs a role, a\n // name and the question read out as its description.\n const pane = this.overlayRef.overlayElement;\n pane.id = this.panelId;\n pane.setAttribute('role', 'dialog');\n pane.setAttribute('aria-modal', 'false');\n pane.setAttribute('aria-label', this.resolvedAriaLabel());\n pane.setAttribute('aria-describedby', this.messageId);\n\n const portal = new ComponentPortal(WrPopconfirmPanel, this.vcr);\n const ref = this.overlayRef.attach(portal);\n ref.setInput('message', this.message());\n ref.setInput('messageId', this.messageId);\n ref.setInput('confirmText', this.resolvedConfirm());\n ref.setInput('cancelText', this.resolvedCancel());\n ref.setInput('confirmColor', this.confirmColor());\n // Render now rather than next frame: the buttons have to exist before focus can\n // move to one, and a deferred focus is the class of bug this repo keeps finding.\n ref.changeDetectorRef.detectChanges();\n // Focus has to enter the panel — the overlay container sits at the end of\n // `<body>`, so Tab from the trigger went to the next thing on the PAGE and the\n // only way to confirm was unreachable. Cancel first: the action being confirmed\n // is usually the destructive one.\n pane.querySelector<HTMLElement>('.wr-popconfirm__actions wr-btn')?.focus();\n this.isOpen.set(true);\n\n ref.instance.confirmed.subscribe(() => {\n this.confirmed.emit();\n this.close();\n });\n ref.instance.cancelled.subscribe(() => this.dismiss());\n\n this.outsideClick\n .outsidePointerEvents(this.overlayRef)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(event => {\n if (this.host.nativeElement.contains(event.target as Node)) return;\n this.dismiss();\n });\n\n this.overlayRef\n .keydownEvents()\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(event => {\n if (event.key === 'Escape') {\n event.preventDefault();\n this.dismiss();\n }\n });\n }\n\n close(): void {\n this.dispose();\n }\n\n private dismiss(): void {\n if (!this.overlayRef) return;\n this.cancelled.emit();\n this.dispose();\n }\n\n private dispose(): void {\n if (!this.overlayRef) return;\n // Focus lives inside the panel while it is open, and removing the panel would\n // drop it to `<body>` — hand it back to the trigger instead, as `wr-dropdown`\n // does on Escape. Only when focus is still IN there: if the user has already\n // clicked elsewhere, taking it back would be stealing.\n const returnFocus = this.overlayRef.overlayElement.contains(document.activeElement);\n this.overlayRef.dispose();\n this.overlayRef = null;\n this.isOpen.set(false);\n if (returnFocus) this.host.nativeElement.focus();\n }\n\n /**\n * Whether the app reads right-to-left.\n *\n * Optional inject: `Directionality` is root-provided, so this is never null in\n * an app — but a bare `TestBed` that provides nothing should still get a\n * component that works, and defaulting to LTR is the honest fallback.\n */\n private isRtl(): boolean {\n return this.dir?.value === 'rtl';\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}