ngwr 14.3.1 → 14.5.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 (368) hide show
  1. package/README.md +4 -4
  2. package/avatar/styles/_index.scss +4 -2
  3. package/badge/styles/_index.scss +4 -1
  4. package/badge/styles/_tag.scss +3 -0
  5. package/cascader/styles/_rules.scss +3 -0
  6. package/command-palette/styles/_index.scss +23 -0
  7. package/context-menu/styles/_index.scss +13 -1
  8. package/fesm2022/ngwr-action-sheet.mjs +3 -3
  9. package/fesm2022/ngwr-affix.mjs +17 -4
  10. package/fesm2022/ngwr-affix.mjs.map +1 -1
  11. package/fesm2022/ngwr-alert.mjs +4 -4
  12. package/fesm2022/ngwr-alert.mjs.map +1 -1
  13. package/fesm2022/ngwr-anchor.mjs +3 -3
  14. package/fesm2022/ngwr-aurora.mjs +3 -3
  15. package/fesm2022/ngwr-avatar.mjs +3 -3
  16. package/fesm2022/ngwr-back-top.mjs +3 -3
  17. package/fesm2022/ngwr-badge.mjs +6 -6
  18. package/fesm2022/ngwr-bar-chart-testing.mjs +18 -2
  19. package/fesm2022/ngwr-bar-chart-testing.mjs.map +1 -1
  20. package/fesm2022/ngwr-bar-chart.mjs +3 -3
  21. package/fesm2022/ngwr-blur-text.mjs +3 -3
  22. package/fesm2022/ngwr-border-glow.mjs +3 -3
  23. package/fesm2022/ngwr-breadcrumbs.mjs +7 -7
  24. package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
  25. package/fesm2022/ngwr-burger.mjs +3 -3
  26. package/fesm2022/ngwr-button.mjs +6 -6
  27. package/fesm2022/ngwr-calendar-heatmap-testing.mjs +12 -9
  28. package/fesm2022/ngwr-calendar-heatmap-testing.mjs.map +1 -1
  29. package/fesm2022/ngwr-calendar-heatmap.mjs +35 -7
  30. package/fesm2022/ngwr-calendar-heatmap.mjs.map +1 -1
  31. package/fesm2022/ngwr-calendar.mjs +32 -4
  32. package/fesm2022/ngwr-calendar.mjs.map +1 -1
  33. package/fesm2022/ngwr-card.mjs +9 -9
  34. package/fesm2022/ngwr-carousel.mjs +6 -6
  35. package/fesm2022/ngwr-cascader-testing.mjs +87 -17
  36. package/fesm2022/ngwr-cascader-testing.mjs.map +1 -1
  37. package/fesm2022/ngwr-cascader.mjs +76 -5
  38. package/fesm2022/ngwr-cascader.mjs.map +1 -1
  39. package/fesm2022/ngwr-checkbox-testing.mjs +13 -2
  40. package/fesm2022/ngwr-checkbox-testing.mjs.map +1 -1
  41. package/fesm2022/ngwr-checkbox.mjs +42 -7
  42. package/fesm2022/ngwr-checkbox.mjs.map +1 -1
  43. package/fesm2022/ngwr-circular-text.mjs +3 -3
  44. package/fesm2022/ngwr-click-spark.mjs +3 -3
  45. package/fesm2022/ngwr-clipboard.mjs +3 -3
  46. package/fesm2022/ngwr-collapse.mjs +9 -9
  47. package/fesm2022/ngwr-color-picker.mjs +24 -8
  48. package/fesm2022/ngwr-color-picker.mjs.map +1 -1
  49. package/fesm2022/ngwr-command-palette.mjs +16 -3
  50. package/fesm2022/ngwr-command-palette.mjs.map +1 -1
  51. package/fesm2022/ngwr-compare.mjs +3 -3
  52. package/fesm2022/ngwr-confetti.mjs +3 -3
  53. package/fesm2022/ngwr-context-menu.mjs +47 -15
  54. package/fesm2022/ngwr-context-menu.mjs.map +1 -1
  55. package/fesm2022/ngwr-cookie.mjs +3 -3
  56. package/fesm2022/ngwr-counter.mjs +6 -6
  57. package/fesm2022/ngwr-date-adapters-fns.mjs +3 -3
  58. package/fesm2022/ngwr-date-adapters-luxon.mjs +3 -3
  59. package/fesm2022/ngwr-date-picker.mjs +111 -28
  60. package/fesm2022/ngwr-date-picker.mjs.map +1 -1
  61. package/fesm2022/ngwr-date.mjs +3 -3
  62. package/fesm2022/ngwr-decrypt-text.mjs +3 -3
  63. package/fesm2022/ngwr-density.mjs +6 -6
  64. package/fesm2022/ngwr-descriptions.mjs +6 -6
  65. package/fesm2022/ngwr-dialog.mjs +27 -16
  66. package/fesm2022/ngwr-dialog.mjs.map +1 -1
  67. package/fesm2022/ngwr-directives.mjs +12 -12
  68. package/fesm2022/ngwr-divider.mjs +3 -3
  69. package/fesm2022/ngwr-donut-chart-testing.mjs +18 -2
  70. package/fesm2022/ngwr-donut-chart-testing.mjs.map +1 -1
  71. package/fesm2022/ngwr-donut-chart.mjs +4 -4
  72. package/fesm2022/ngwr-donut-chart.mjs.map +1 -1
  73. package/fesm2022/ngwr-drag-drop.mjs +7 -7
  74. package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
  75. package/fesm2022/ngwr-drawer.mjs +66 -20
  76. package/fesm2022/ngwr-drawer.mjs.map +1 -1
  77. package/fesm2022/ngwr-dropdown.mjs +54 -16
  78. package/fesm2022/ngwr-dropdown.mjs.map +1 -1
  79. package/fesm2022/ngwr-empty.mjs +3 -3
  80. package/fesm2022/ngwr-event-calendar.mjs +6 -6
  81. package/fesm2022/ngwr-falling-text.mjs +3 -3
  82. package/fesm2022/ngwr-file-upload.mjs +18 -5
  83. package/fesm2022/ngwr-file-upload.mjs.map +1 -1
  84. package/fesm2022/ngwr-form.mjs +66 -14
  85. package/fesm2022/ngwr-form.mjs.map +1 -1
  86. package/fesm2022/ngwr-fuzzy-text.mjs +3 -3
  87. package/fesm2022/ngwr-gauge-testing.mjs +16 -2
  88. package/fesm2022/ngwr-gauge-testing.mjs.map +1 -1
  89. package/fesm2022/ngwr-gauge.mjs +3 -3
  90. package/fesm2022/ngwr-glitch-text.mjs +3 -3
  91. package/fesm2022/ngwr-gradient-text.mjs +3 -3
  92. package/fesm2022/ngwr-graph-testing.mjs +243 -0
  93. package/fesm2022/ngwr-graph-testing.mjs.map +1 -0
  94. package/fesm2022/ngwr-graph.mjs +1112 -0
  95. package/fesm2022/ngwr-graph.mjs.map +1 -0
  96. package/fesm2022/ngwr-hotkey.mjs +6 -6
  97. package/fesm2022/ngwr-i18n-ar.mjs +7 -0
  98. package/fesm2022/ngwr-i18n-ar.mjs.map +1 -1
  99. package/fesm2022/ngwr-i18n-cs.mjs +7 -0
  100. package/fesm2022/ngwr-i18n-cs.mjs.map +1 -1
  101. package/fesm2022/ngwr-i18n-de.mjs +7 -0
  102. package/fesm2022/ngwr-i18n-de.mjs.map +1 -1
  103. package/fesm2022/ngwr-i18n-en.mjs +23 -2
  104. package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
  105. package/fesm2022/ngwr-i18n-es.mjs +7 -0
  106. package/fesm2022/ngwr-i18n-es.mjs.map +1 -1
  107. package/fesm2022/ngwr-i18n-fr.mjs +7 -0
  108. package/fesm2022/ngwr-i18n-fr.mjs.map +1 -1
  109. package/fesm2022/ngwr-i18n-he.mjs +7 -0
  110. package/fesm2022/ngwr-i18n-he.mjs.map +1 -1
  111. package/fesm2022/ngwr-i18n-hi.mjs +7 -0
  112. package/fesm2022/ngwr-i18n-hi.mjs.map +1 -1
  113. package/fesm2022/ngwr-i18n-id.mjs +7 -0
  114. package/fesm2022/ngwr-i18n-id.mjs.map +1 -1
  115. package/fesm2022/ngwr-i18n-it.mjs +7 -0
  116. package/fesm2022/ngwr-i18n-it.mjs.map +1 -1
  117. package/fesm2022/ngwr-i18n-ja.mjs +7 -0
  118. package/fesm2022/ngwr-i18n-ja.mjs.map +1 -1
  119. package/fesm2022/ngwr-i18n-ko.mjs +7 -0
  120. package/fesm2022/ngwr-i18n-ko.mjs.map +1 -1
  121. package/fesm2022/ngwr-i18n-nl.mjs +7 -0
  122. package/fesm2022/ngwr-i18n-nl.mjs.map +1 -1
  123. package/fesm2022/ngwr-i18n-pl.mjs +7 -0
  124. package/fesm2022/ngwr-i18n-pl.mjs.map +1 -1
  125. package/fesm2022/ngwr-i18n-pt.mjs +7 -0
  126. package/fesm2022/ngwr-i18n-pt.mjs.map +1 -1
  127. package/fesm2022/ngwr-i18n-ru.mjs +7 -0
  128. package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
  129. package/fesm2022/ngwr-i18n-sv.mjs +7 -0
  130. package/fesm2022/ngwr-i18n-sv.mjs.map +1 -1
  131. package/fesm2022/ngwr-i18n-tr.mjs +7 -0
  132. package/fesm2022/ngwr-i18n-tr.mjs.map +1 -1
  133. package/fesm2022/ngwr-i18n-uk.mjs +7 -0
  134. package/fesm2022/ngwr-i18n-uk.mjs.map +1 -1
  135. package/fesm2022/ngwr-i18n-vi.mjs +7 -0
  136. package/fesm2022/ngwr-i18n-vi.mjs.map +1 -1
  137. package/fesm2022/ngwr-i18n-zh-TW.mjs +7 -0
  138. package/fesm2022/ngwr-i18n-zh-TW.mjs.map +1 -1
  139. package/fesm2022/ngwr-i18n-zh.mjs +7 -0
  140. package/fesm2022/ngwr-i18n-zh.mjs.map +1 -1
  141. package/fesm2022/ngwr-i18n.mjs +9 -9
  142. package/fesm2022/ngwr-icon.mjs +6 -6
  143. package/fesm2022/ngwr-image-cropper.mjs +3 -3
  144. package/fesm2022/ngwr-input-number.mjs +15 -6
  145. package/fesm2022/ngwr-input-number.mjs.map +1 -1
  146. package/fesm2022/ngwr-input-otp.mjs +38 -6
  147. package/fesm2022/ngwr-input-otp.mjs.map +1 -1
  148. package/fesm2022/ngwr-input.mjs +15 -15
  149. package/fesm2022/ngwr-keyboard.mjs +3 -3
  150. package/fesm2022/ngwr-knob-testing.mjs +11 -3
  151. package/fesm2022/ngwr-knob-testing.mjs.map +1 -1
  152. package/fesm2022/ngwr-knob.mjs +19 -4
  153. package/fesm2022/ngwr-knob.mjs.map +1 -1
  154. package/fesm2022/ngwr-layout.mjs +15 -15
  155. package/fesm2022/ngwr-lightbox.mjs +27 -6
  156. package/fesm2022/ngwr-lightbox.mjs.map +1 -1
  157. package/fesm2022/ngwr-line-chart-testing.mjs +18 -2
  158. package/fesm2022/ngwr-line-chart-testing.mjs.map +1 -1
  159. package/fesm2022/ngwr-line-chart.mjs +22 -4
  160. package/fesm2022/ngwr-line-chart.mjs.map +1 -1
  161. package/fesm2022/ngwr-list.mjs +7 -7
  162. package/fesm2022/ngwr-list.mjs.map +1 -1
  163. package/fesm2022/ngwr-loading-bar.mjs +6 -6
  164. package/fesm2022/ngwr-markdown.mjs +6 -6
  165. package/fesm2022/ngwr-marquee.mjs +3 -3
  166. package/fesm2022/ngwr-media.mjs +3 -3
  167. package/fesm2022/ngwr-mention.mjs +24 -8
  168. package/fesm2022/ngwr-mention.mjs.map +1 -1
  169. package/fesm2022/ngwr-meta.mjs +6 -6
  170. package/fesm2022/ngwr-meter-group.mjs +3 -3
  171. package/fesm2022/ngwr-overlay.mjs +125 -10
  172. package/fesm2022/ngwr-overlay.mjs.map +1 -1
  173. package/fesm2022/ngwr-page-header.mjs +3 -3
  174. package/fesm2022/ngwr-pagination.mjs +33 -6
  175. package/fesm2022/ngwr-pagination.mjs.map +1 -1
  176. package/fesm2022/ngwr-pipes.mjs +21 -21
  177. package/fesm2022/ngwr-platform.mjs +9 -9
  178. package/fesm2022/ngwr-popconfirm.mjs +25 -9
  179. package/fesm2022/ngwr-popconfirm.mjs.map +1 -1
  180. package/fesm2022/ngwr-popover-testing.mjs +22 -5
  181. package/fesm2022/ngwr-popover-testing.mjs.map +1 -1
  182. package/fesm2022/ngwr-popover.mjs +243 -37
  183. package/fesm2022/ngwr-popover.mjs.map +1 -1
  184. package/fesm2022/ngwr-progress.mjs +3 -3
  185. package/fesm2022/ngwr-pull-to-refresh.mjs +3 -3
  186. package/fesm2022/ngwr-qr.mjs +3 -3
  187. package/fesm2022/ngwr-radio.mjs +6 -6
  188. package/fesm2022/ngwr-rating-testing.mjs +12 -3
  189. package/fesm2022/ngwr-rating-testing.mjs.map +1 -1
  190. package/fesm2022/ngwr-rating.mjs +19 -4
  191. package/fesm2022/ngwr-rating.mjs.map +1 -1
  192. package/fesm2022/ngwr-result.mjs +13 -13
  193. package/fesm2022/ngwr-result.mjs.map +1 -1
  194. package/fesm2022/ngwr-rotating-text.mjs +3 -3
  195. package/fesm2022/ngwr-schema-form.mjs +3 -3
  196. package/fesm2022/ngwr-scroll.mjs +3 -3
  197. package/fesm2022/ngwr-segmented.mjs +37 -4
  198. package/fesm2022/ngwr-segmented.mjs.map +1 -1
  199. package/fesm2022/ngwr-select.mjs +24 -10
  200. package/fesm2022/ngwr-select.mjs.map +1 -1
  201. package/fesm2022/ngwr-shiny-text.mjs +6 -6
  202. package/fesm2022/ngwr-sidebar.mjs +3 -3
  203. package/fesm2022/ngwr-skeleton.mjs +3 -3
  204. package/fesm2022/ngwr-slider.mjs +18 -5
  205. package/fesm2022/ngwr-slider.mjs.map +1 -1
  206. package/fesm2022/ngwr-sparkline.mjs +3 -3
  207. package/fesm2022/ngwr-speed-dial.mjs +3 -3
  208. package/fesm2022/ngwr-spinner.mjs +3 -3
  209. package/fesm2022/ngwr-splash-cursor.mjs +3 -3
  210. package/fesm2022/ngwr-split-text.mjs +3 -3
  211. package/fesm2022/ngwr-splitter.mjs +3 -3
  212. package/fesm2022/ngwr-spotlight-card.mjs +6 -6
  213. package/fesm2022/ngwr-squircle.mjs +28 -9
  214. package/fesm2022/ngwr-squircle.mjs.map +1 -1
  215. package/fesm2022/ngwr-star-border.mjs +3 -3
  216. package/fesm2022/ngwr-statistic.mjs +20 -13
  217. package/fesm2022/ngwr-statistic.mjs.map +1 -1
  218. package/fesm2022/ngwr-stepper.mjs +6 -6
  219. package/fesm2022/ngwr-storage.mjs +3 -3
  220. package/fesm2022/ngwr-switch.mjs +3 -3
  221. package/fesm2022/ngwr-table.mjs +18 -18
  222. package/fesm2022/ngwr-tabs-router.mjs +3 -3
  223. package/fesm2022/ngwr-tabs.mjs +6 -6
  224. package/fesm2022/ngwr-textarea.mjs +3 -3
  225. package/fesm2022/ngwr-theme.mjs +3 -3
  226. package/fesm2022/ngwr-tilt-card.mjs +6 -6
  227. package/fesm2022/ngwr-timeline.mjs +6 -6
  228. package/fesm2022/ngwr-toast.mjs +29 -12
  229. package/fesm2022/ngwr-toast.mjs.map +1 -1
  230. package/fesm2022/ngwr-toolbar.mjs +3 -3
  231. package/fesm2022/ngwr-tour.mjs +26 -12
  232. package/fesm2022/ngwr-tour.mjs.map +1 -1
  233. package/fesm2022/ngwr-transfer.mjs +88 -11
  234. package/fesm2022/ngwr-transfer.mjs.map +1 -1
  235. package/fesm2022/ngwr-tree-testing.mjs +24 -0
  236. package/fesm2022/ngwr-tree-testing.mjs.map +1 -1
  237. package/fesm2022/ngwr-tree.mjs +81 -9
  238. package/fesm2022/ngwr-tree.mjs.map +1 -1
  239. package/fesm2022/ngwr-typewriter.mjs +3 -3
  240. package/fesm2022/ngwr-typography.mjs +3 -3
  241. package/fesm2022/ngwr-version.mjs +1 -1
  242. package/fesm2022/ngwr-version.mjs.map +1 -1
  243. package/fesm2022/ngwr-virtual-scroll.mjs +3 -3
  244. package/fesm2022/ngwr-waves.mjs +3 -3
  245. package/fesm2022/ngwr-window.mjs +30 -13
  246. package/fesm2022/ngwr-window.mjs.map +1 -1
  247. package/form/styles/_index.scss +63 -0
  248. package/graph/styles/_index.scss +113 -0
  249. package/i18n/ar.json +9 -2
  250. package/i18n/cs.json +9 -2
  251. package/i18n/de.json +9 -2
  252. package/i18n/en.json +11 -4
  253. package/i18n/es.json +9 -2
  254. package/i18n/fr.json +9 -2
  255. package/i18n/he.json +9 -2
  256. package/i18n/hi.json +9 -2
  257. package/i18n/id.json +9 -2
  258. package/i18n/it.json +9 -2
  259. package/i18n/ja.json +9 -2
  260. package/i18n/ko.json +9 -2
  261. package/i18n/nl.json +9 -2
  262. package/i18n/pl.json +9 -2
  263. package/i18n/pt.json +9 -2
  264. package/i18n/ru.json +9 -2
  265. package/i18n/sv.json +9 -2
  266. package/i18n/tr.json +9 -2
  267. package/i18n/uk.json +9 -2
  268. package/i18n/vi.json +9 -2
  269. package/i18n/zh-TW.json +9 -2
  270. package/i18n/zh.json +9 -2
  271. package/input-otp/styles/_index.scss +5 -1
  272. package/line-chart/styles/_index.scss +5 -3
  273. package/llms-full.txt +13 -3
  274. package/llms.txt +8 -6
  275. package/markdown/styles/_index.scss +4 -1
  276. package/mention/styles/_index.scss +22 -1
  277. package/package.json +10 -1
  278. package/radio/styles/_index.scss +3 -0
  279. package/result/styles/_index.scss +12 -0
  280. package/schematics/migrations/v14/index.js +6 -3
  281. package/schematics/migrations.json +1 -1
  282. package/schematics/ng-add/index.js +34 -5
  283. package/schematics/use/symbol-map.json +2 -0
  284. package/segmented/styles/_index.scss +12 -1
  285. package/select/styles/_index.scss +20 -1
  286. package/skills/ngwr/SKILL.md +1 -1
  287. package/skills/ngwr/references/catalog.md +2 -0
  288. package/statistic/styles/_index.scss +4 -0
  289. package/stepper/styles/_index.scss +36 -0
  290. package/styles.scss +1 -0
  291. package/switch/styles/_index.scss +3 -0
  292. package/table/styles/_index.scss +12 -0
  293. package/tabs/styles/_index.scss +4 -1
  294. package/textarea/styles/_index.scss +6 -1
  295. package/theme/styles/_colors.scss +11 -0
  296. package/theme/styles/_contrast.scss +136 -0
  297. package/theme/styles/_focus.scss +7 -0
  298. package/theme/styles/_index.scss +1 -0
  299. package/theme/styles/_mixins.scss +15 -8
  300. package/timeline/styles/_index.scss +28 -1
  301. package/toast/styles/_index.scss +11 -0
  302. package/tree/styles/_index.scss +27 -1
  303. package/types/ngwr-badge.d.ts +1 -1
  304. package/types/ngwr-bar-chart-testing.d.ts +11 -1
  305. package/types/ngwr-button.d.ts +1 -1
  306. package/types/ngwr-calendar-heatmap-testing.d.ts +10 -5
  307. package/types/ngwr-calendar-heatmap.d.ts +22 -0
  308. package/types/ngwr-calendar.d.ts +21 -0
  309. package/types/ngwr-cascader-testing.d.ts +74 -17
  310. package/types/ngwr-cascader.d.ts +35 -0
  311. package/types/ngwr-checkbox-testing.d.ts +12 -1
  312. package/types/ngwr-checkbox.d.ts +10 -0
  313. package/types/ngwr-clipboard.d.ts +1 -1
  314. package/types/ngwr-color-picker.d.ts +8 -0
  315. package/types/ngwr-confetti.d.ts +1 -1
  316. package/types/ngwr-context-menu.d.ts +10 -0
  317. package/types/ngwr-cookie.d.ts +1 -1
  318. package/types/ngwr-date-adapters-fns.d.ts +1 -1
  319. package/types/ngwr-date-adapters-luxon.d.ts +1 -1
  320. package/types/ngwr-date-picker.d.ts +16 -0
  321. package/types/ngwr-date.d.ts +9 -3
  322. package/types/ngwr-density.d.ts +1 -1
  323. package/types/ngwr-dialog.d.ts +2 -1
  324. package/types/ngwr-donut-chart-testing.d.ts +11 -1
  325. package/types/ngwr-drawer.d.ts +29 -1
  326. package/types/ngwr-dropdown.d.ts +25 -0
  327. package/types/ngwr-file-upload.d.ts +11 -0
  328. package/types/ngwr-form.d.ts +25 -0
  329. package/types/ngwr-gauge-testing.d.ts +9 -1
  330. package/types/ngwr-graph-testing.d.ts +190 -0
  331. package/types/ngwr-graph.d.ts +203 -0
  332. package/types/ngwr-hotkey.d.ts +1 -1
  333. package/types/ngwr-i18n.d.ts +1 -1
  334. package/types/ngwr-input-number.d.ts +12 -2
  335. package/types/ngwr-input-otp.d.ts +12 -0
  336. package/types/ngwr-knob-testing.d.ts +11 -3
  337. package/types/ngwr-knob.d.ts +13 -0
  338. package/types/ngwr-lightbox.d.ts +15 -0
  339. package/types/ngwr-line-chart-testing.d.ts +11 -1
  340. package/types/ngwr-line-chart.d.ts +18 -0
  341. package/types/ngwr-loading-bar.d.ts +1 -1
  342. package/types/ngwr-markdown.d.ts +1 -1
  343. package/types/ngwr-media.d.ts +1 -1
  344. package/types/ngwr-mention.d.ts +7 -0
  345. package/types/ngwr-meta.d.ts +1 -1
  346. package/types/ngwr-overlay.d.ts +64 -6
  347. package/types/ngwr-pagination.d.ts +16 -0
  348. package/types/ngwr-platform.d.ts +3 -3
  349. package/types/ngwr-popconfirm.d.ts +1 -0
  350. package/types/ngwr-popover-testing.d.ts +22 -5
  351. package/types/ngwr-popover.d.ts +44 -8
  352. package/types/ngwr-rating-testing.d.ts +12 -3
  353. package/types/ngwr-rating.d.ts +13 -0
  354. package/types/ngwr-scroll.d.ts +1 -1
  355. package/types/ngwr-segmented.d.ts +16 -0
  356. package/types/ngwr-select.d.ts +7 -0
  357. package/types/ngwr-squircle.d.ts +22 -3
  358. package/types/ngwr-statistic.d.ts +0 -1
  359. package/types/ngwr-storage.d.ts +1 -1
  360. package/types/ngwr-theme.d.ts +1 -1
  361. package/types/ngwr-toast.d.ts +3 -1
  362. package/types/ngwr-tour.d.ts +7 -1
  363. package/types/ngwr-transfer.d.ts +52 -0
  364. package/types/ngwr-tree-testing.d.ts +20 -0
  365. package/types/ngwr-tree.d.ts +43 -1
  366. package/types/ngwr-version.d.ts +1 -1
  367. package/types/ngwr-window.d.ts +2 -1
  368. package/typography/styles/_index.scss +26 -4
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-overlay.mjs","sources":["../../../projects/lib/overlay/wr-overlay-close.ts","../../../projects/lib/overlay/wr-mirror-offsets.ts","../../../projects/lib/overlay/wr-outside-click.ts","../../../projects/lib/overlay/wr-overlay-container.ts","../../../projects/lib/overlay/tokens/wr-overlay.token.ts","../../../projects/lib/overlay/tokens/wr-overlay-container.token.ts","../../../projects/lib/overlay/tokens/wr-responsive-overlays.token.ts","../../../projects/lib/overlay/provide-wr-overlay.ts","../../../projects/lib/overlay/provide-wr-responsive-overlays.ts","../../../projects/lib/overlay/ngwr-overlay.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\nconst SVG_NS = 'http://www.w3.org/2000/svg';\n\n/** The same 24×24 stroked ✕ the rest of the library's chrome draws (alert, toast, lightbox). */\nconst CLOSE_ICON_ATTRS: readonly (readonly [string, string])[] = [\n ['class', 'wr-icon__svg'],\n ['viewBox', '0 0 24 24'],\n ['fill', 'none'],\n ['stroke', 'currentColor'],\n ['stroke-width', '2'],\n ['stroke-linecap', 'round'],\n ['stroke-linejoin', 'round'],\n ['aria-hidden', 'true'],\n];\nconst CLOSE_ICON_PATHS: readonly string[] = ['M18 6 6 18', 'm6 6 12 12'];\n\n/**\n * Builds the ✕ node by node.\n *\n * It was one `innerHTML = CLOSE_ICON`, and the string was a compile-time\n * constant, so it was never an injection risk — it was an AVAILABILITY one.\n * Under `require-trusted-types-for 'script'` an `innerHTML` write throws\n * `TrustedHTML assignment` whatever the string is, and the throw landed after\n * the overlay was on screen: a modal with no ✕, no backdrop subscription and no\n * Escape handler, over the whole application. `createElementNS` is not a\n * Trusted Types sink, so there is nothing left to police.\n */\nfunction createCloseIcon(doc: Document): SVGSVGElement {\n const svg = doc.createElementNS(SVG_NS, 'svg');\n // `setAttribute`, not `.className` — on an SVG element that property is an\n // `SVGAnimatedString` and assigning a string to it silently does nothing.\n for (const [name, value] of CLOSE_ICON_ATTRS) svg.setAttribute(name, value);\n for (const d of CLOSE_ICON_PATHS) {\n const path = doc.createElementNS(SVG_NS, 'path');\n path.setAttribute('d', d);\n svg.appendChild(path);\n }\n return svg;\n}\n\n/**\n * Appends a dismiss (✕) button to a service-opened overlay panel.\n *\n * `WrDialog` and `WrDrawerManager` build their panel around a component the\n * consumer supplies, so there is no template of their own to put a corner button\n * in — they call this instead. Component-driven overlays (`<wr-drawer>`) render\n * the same markup in their template.\n *\n * Uses `host.ownerDocument` rather than the global `document`, so it carries no\n * hidden browser-only assumption; callers still gate on the platform because\n * they have nothing to append to on the server.\n *\n * @param host Panel element the button is appended to (and positioned against).\n * @param className BEM class for the button, e.g. `wr-dialog__close`.\n * @param label Accessible name — already localized by the caller.\n * @param onClose Invoked on click.\n */\nexport function wrAppendOverlayClose(\n host: HTMLElement,\n className: string,\n label: string,\n onClose: () => void\n): HTMLButtonElement {\n const button = host.ownerDocument.createElement('button');\n button.type = 'button';\n button.className = className;\n button.setAttribute('aria-label', label);\n button.appendChild(createCloseIcon(host.ownerDocument));\n button.addEventListener('click', onClose);\n host.appendChild(button);\n return button;\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 type { ConnectedPosition } from '@angular/cdk/overlay';\n\n/**\n * Mirror the horizontal offsets of a connected-position list for RTL.\n *\n * The CDK mirrors `originX` / `overlayX` under `dir=\"rtl\"` — a `start` anchor\n * resolves to the origin's right edge — but it does NOT mirror `offsetX`, which\n * it adds to the final PHYSICAL x (`_getOffset` returns `position.offsetX`\n * verbatim). So a position that meant \"sit to the inline-start of the trigger,\n * 8px clear of it\" keeps its `-8` under RTL, where the panel is now on the\n * right: the gap becomes an 8px OVERLAP, and the panel sits on top of the thing\n * it is describing.\n *\n * Nothing in the CDK will do this for us, and the amount is per position, so\n * every ngwr overlay that offsets along the inline axis passes its list through\n * here. `offsetY` is untouched: the block axis does not flip.\n *\n * @example\n * ```ts\n * const dir = inject(Directionality, { optional: true });\n *\n * strategy.withPositions(wrMirrorOffsets(WR_POPOVER_POSITIONS[position], dir?.value === 'rtl'));\n * ```\n */\nexport function wrMirrorOffsets(positions: readonly ConnectedPosition[], isRtl: boolean): ConnectedPosition[] {\n // Copied rather than mutated even when there is nothing to do: the position\n // tables are module-level constants shared by every instance, so handing back\n // the same objects invites a caller to write through them.\n if (!isRtl) return positions.map(position => ({ ...position }));\n\n return positions.map(position => ({\n ...position,\n ...(position.offsetX == null ? {} : { offsetX: -position.offsetX }),\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 type { OverlayRef } from '@angular/cdk/overlay';\nimport { DOCUMENT, isPlatformBrowser } from '@angular/common';\nimport { PLATFORM_ID, Service, inject } from '@angular/core';\n\nimport { Observable, type Subscriber } from 'rxjs';\n\n/** One live subscription to `WrOutsideClick.outsidePointerEvents()`. */\ninterface Watcher {\n readonly overlayRef: OverlayRef;\n readonly subscriber: Subscriber<MouseEvent>;\n}\n\n/**\n * Shadow-piercing `event.target` — `composedPath()[0]` is the real originator\n * when the click started inside a shadow root, where `target` is retargeted to\n * the host.\n */\nfunction eventTarget(event: Event): EventTarget | null {\n if (event.composedPath) {\n try {\n return event.composedPath()[0] ?? event.target;\n } catch {\n /* Detached / synthetic events can throw — fall through to `target`. */\n }\n }\n return event.target;\n}\n\n/** `parent.contains(child)`, but stepping out of shadow roots through their hosts. */\nfunction containsAcrossShadow(parent: Node, child: EventTarget | null): boolean {\n const hasShadowRoot = typeof ShadowRoot !== 'undefined';\n let current = child as Node | null;\n while (current) {\n if (current === parent) return true;\n current = hasShadowRoot && current instanceof ShadowRoot ? current.host : current.parentNode;\n }\n return false;\n}\n\n/**\n * Outside-click source for overlays — a drop-in replacement for\n * `OverlayRef.outsidePointerEvents()`.\n *\n * **Why this exists.** CDK's `OverlayOutsideClickDispatcher` binds its\n * listeners to `document.body`. When page content is shorter than the viewport,\n * a click in the empty space below it targets `<html>` — and `<html>` is\n * `body`'s *parent*, so the event bubbles straight to the document and `body`\n * never sees it. The overlay silently stays open. Listening on the document\n * itself catches both cases, and costs nothing else.\n *\n * Semantics are otherwise identical to the CDK's, deliberately:\n *\n * - Emits on `click` / `auxclick` / `contextmenu`, in the capture phase, and\n * tracks `pointerdown` so a `click` is judged by where the press *started*\n * (a drag that ends outside the pane doesn't count as an outside click).\n * - Walks watchers top-most first and stops at the first one that contains the\n * event, so clicking inside a stacked overlay can't close the ones beneath\n * it (a `wr-select` opened inside a `wr-popover`, say).\n * - Fires for the very click that opened the overlay, which is why every caller\n * also ignores events landing on its own trigger.\n *\n * Registration is per subscription: the document listeners go up with the first\n * watcher and come down with the last, so an app with no open overlay has none.\n * That sentence was aspirational until v11 — see {@link outsidePointerEvents}.\n */\n@Service()\nexport class WrOutsideClick {\n private readonly doc = inject(DOCUMENT);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n /** In attach order — last is top-most. */\n private readonly watchers: Watcher[] = [];\n private cleanup: (() => void) | null = null;\n private pressOrigin: EventTarget | null = null;\n\n /**\n * Emits every `click` / `auxclick` / `contextmenu` that lands outside the\n * given overlay's pane, for as long as the overlay is attached.\n *\n * **It completes when the overlay detaches, and that is load-bearing.** Every\n * one of the ten call sites subscribes inside its own `openOverlay()` and\n * pipes `takeUntilDestroyed(destroyRef)` — a DIRECTIVE lifetime, not an\n * overlay one — and none of them unsubscribes on close, because the natural\n * reading of that idiom is \"this ends with the component\". Without the\n * completion below the teardown never ran: one watcher accumulated per OPEN\n * for the life of the page, each pinning a disposed `OverlayRef` (and through\n * it a detached pane, its portal outlet and their injectors), the four\n * capture-phase document listeners could never come down because\n * `watchers.length` never reached zero, and every click on the page walked a\n * list that only grew. A `mode=\"tooltip\"` popover made it unbounded — one\n * permanent watcher per hover.\n *\n * Completing here rather than fixing ten call sites is deliberate: the next\n * component to open an overlay would have made the same reasonable mistake.\n * It is also what CDK's own `OverlayRef.outsidePointerEvents()` does.\n */\n outsidePointerEvents(overlayRef: OverlayRef): Observable<MouseEvent> {\n return new Observable<MouseEvent>(subscriber => {\n if (!this.isBrowser) return;\n\n const watcher: Watcher = { overlayRef, subscriber };\n this.watchers.push(watcher);\n if (this.watchers.length === 1) this.listen();\n\n // BOTH handlers, and the second one is not defensive padding. `dispose()`\n // emits a detachment and then completes the subject, so a live overlay\n // arrives through `next` — but a ref that was already disposed before\n // anyone subscribed has nothing left to emit and arrives through\n // `complete` alone. Listening for `next` only left exactly the watcher\n // this whole change exists to remove.\n const ended = (): void => subscriber.complete();\n const detached = overlayRef.detachments().subscribe({ next: ended, complete: ended });\n\n return () => {\n detached.unsubscribe();\n const index = this.watchers.indexOf(watcher);\n if (index > -1) this.watchers.splice(index, 1);\n if (!this.watchers.length) this.unlisten();\n };\n });\n }\n\n private readonly onPointerDown = (event: Event): void => {\n this.pressOrigin = eventTarget(event);\n };\n\n private readonly onClick = (event: Event): void => {\n const target = eventTarget(event);\n // `detail > 0` means the click really came from a pointer press. A click\n // activated by Enter or Space carries `detail: 0` and has no `pointerdown`\n // of its own — so trusting a leftover origin there judged it by a press\n // that belonged to something else entirely. A press inside the pane that\n // never produced a click (a drag released off-window, a node removed under\n // the finger, a cancelled touch) survives in `pressOrigin`, and the next\n // keyboard activation anywhere on the page then read as \"inside\": the panel\n // would not close, for keyboard users only.\n const fromPointer = event.type === 'click' && (event as MouseEvent).detail > 0;\n const origin = fromPointer && this.pressOrigin ? this.pressOrigin : target;\n this.pressOrigin = null;\n\n // Snapshot: a watcher that closes on this event unsubscribes synchronously,\n // mutating `watchers` while we're walking it.\n const watchers = this.watchers.slice();\n for (let i = watchers.length - 1; i > -1; i--) {\n const { overlayRef, subscriber } = watchers[i];\n if (!overlayRef.hasAttached()) continue;\n\n const pane = overlayRef.overlayElement;\n if (containsAcrossShadow(pane, target) || containsAcrossShadow(pane, origin)) break;\n\n subscriber.next(event as MouseEvent);\n }\n };\n\n private listen(): void {\n const options: AddEventListenerOptions = { capture: true };\n const doc = this.doc;\n\n doc.addEventListener('pointerdown', this.onPointerDown, options);\n doc.addEventListener('click', this.onClick, options);\n doc.addEventListener('auxclick', this.onClick, options);\n doc.addEventListener('contextmenu', this.onClick, options);\n\n this.cleanup = () => {\n doc.removeEventListener('pointerdown', this.onPointerDown, options);\n doc.removeEventListener('click', this.onClick, options);\n doc.removeEventListener('auxclick', this.onClick, options);\n doc.removeEventListener('contextmenu', this.onClick, options);\n };\n }\n\n private unlisten(): void {\n this.cleanup?.();\n this.cleanup = null;\n this.pressOrigin = null;\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 { OverlayContainer } from '@angular/cdk/overlay';\nimport { Service } from '@angular/core';\n\n/**\n * Custom CDK `OverlayContainer` subclass that tags its DOM element with\n * `.wr-overlay-container` in addition to CDK's own `.cdk-overlay-container`.\n *\n * Why: CDK uses a single overlay container per app — every CDK consumer\n * (this lib, Angular Material, NG-ZORRO, etc.) puts its overlays in the\n * same root element. With this class applied you can scope NGWR-specific\n * overlay styles via the tag, e.g.:\n *\n * ```scss\n * .wr-overlay-container .cdk-overlay-pane { z-index: 1100; }\n * ```\n *\n * It does **not** isolate two libraries that both subclass OverlayContainer\n * — the last provider wins. It does give NGWR overlays a stable CSS hook.\n */\n@Service()\nexport class WrOverlayContainer extends OverlayContainer {\n protected override _createContainer(): void {\n super._createContainer();\n this._containerElement?.classList.add('wr-overlay-container');\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 { Overlay } from '@angular/cdk/overlay';\nimport { InjectionToken, inject } from '@angular/core';\n\n/**\n * Injection token for the CDK `Overlay` service NGWR components should\n * use to open panels.\n *\n * Defaults to CDK's root `Overlay` (shared with every other CDK consumer\n * in the app). Call `provideWrOverlay()` to bind it to an isolated\n * `Overlay` instance backed by a separate `OverlayContainer` — that way\n * NGWR overlays don't share the same DOM root with other libraries.\n *\n * @internal — directives/services inside the lib inject this instead of\n * CDK's `Overlay` directly.\n */\nexport const WR_OVERLAY = new InjectionToken<Overlay>('WR_OVERLAY', {\n providedIn: 'root',\n factory: () => inject(Overlay),\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 { OverlayContainer } from '@angular/cdk/overlay';\nimport { InjectionToken, inject } from '@angular/core';\n\n/**\n * Injection token for the overlay container NGWR components should use.\n *\n * Defaults to CDK's `OverlayContainer` — i.e. the same root element every\n * CDK consumer shares. Call `provideWrOverlay()` to replace it with an\n * isolated instance so NGWR overlays don't collide with other libraries.\n *\n * @internal\n */\nexport const WR_OVERLAY_CONTAINER = new InjectionToken<OverlayContainer>('WR_OVERLAY_CONTAINER', {\n providedIn: 'root',\n factory: () => inject(OverlayContainer),\n});\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { InjectionToken } from '@angular/core';\n\n/** Configuration for responsive (bottom-sheet) overlay presentation. */\ninterface WrResponsiveOverlaysConfig {\n /**\n * Viewport width (CSS px) at or below which overlays present as a\n * bottom-sheet instead of a floating panel. @default 640\n */\n readonly breakpoint: number;\n}\n\n/**\n * When set, overlay services (dialog, select, dropdown, …) present as a\n * slide-up bottom-sheet on viewports at or below `breakpoint`. `null`\n * (the default) keeps every overlay floating. Configure via\n * {@link provideWrResponsiveOverlays}; override per call with a\n * component's `responsive` option.\n *\n * @internal\n */\nconst WR_RESPONSIVE_OVERLAYS = new InjectionToken<WrResponsiveOverlaysConfig | null>('WR_RESPONSIVE_OVERLAYS', {\n factory: () => null,\n});\n\n/**\n * Decide whether an overlay should present as a bottom-sheet for the\n * current viewport.\n *\n * - `responsive === true` — sheet on small viewports regardless of config.\n * - `responsive === false` — never a sheet.\n * - `responsive === undefined` — follow the global config (sheet when\n * {@link provideWrResponsiveOverlays} is configured).\n *\n * SSR-safe: returns `false` when there's no `window`.\n *\n * @internal\n */\nfunction wrPresentAsSheet(responsive: boolean | undefined, config: WrResponsiveOverlaysConfig | null): boolean {\n const enabled = responsive ?? config !== null;\n if (!enabled || typeof window === 'undefined') return false;\n return window.innerWidth <= (config?.breakpoint ?? 640);\n}\n\nexport { WR_RESPONSIVE_OVERLAYS, wrPresentAsSheet };\nexport type { WrResponsiveOverlaysConfig };\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 { Overlay, OverlayContainer } from '@angular/cdk/overlay';\nimport {\n EnvironmentInjector,\n Injector,\n type EnvironmentProviders,\n inject,\n makeEnvironmentProviders,\n provideEnvironmentInitializer,\n} from '@angular/core';\n\nimport { WrVisualViewport } from 'ngwr/platform';\n\nimport { WR_OVERLAY, WR_OVERLAY_CONTAINER } from './tokens';\nimport { WrOverlayContainer } from './wr-overlay-container';\n\n/**\n * Isolates NGWR overlays from other CDK consumers in the app.\n *\n * Without this call, NGWR overlays use CDK's root `Overlay` — they\n * render into the same `.cdk-overlay-container` element as Angular\n * Material, NG-ZORRO, etc. With it, NGWR gets its own `OverlayContainer`\n * (marked `.wr-overlay-container`) **and** its own `Overlay` service\n * instance — so styles, z-index, and lifecycle never collide.\n *\n * It does this by replacing two injection tokens:\n * - `WR_OVERLAY_CONTAINER` → custom `WrOverlayContainer` subclass\n * - `WR_OVERLAY` → a fresh `Overlay` instance built in a child injector\n * that resolves `OverlayContainer` to the custom subclass\n *\n * CDK's own root `Overlay` / `OverlayContainer` are left untouched, so\n * other libraries keep working with their original container.\n *\n * @example\n * ```ts\n * import { provideWrOverlay } from 'ngwr/overlay';\n *\n * bootstrapApplication(AppComponent, {\n * providers: [\n * provideWrOverlay(),\n * ],\n * });\n * ```\n */\nexport function provideWrOverlay(): EnvironmentProviders {\n return makeEnvironmentProviders([\n // Track the visual viewport app-wide so overlay sheets (and the\n // command-palette) can lift above the on-screen keyboard. No-op on the\n // server / in browsers without the API.\n provideEnvironmentInitializer(() => void inject(WrVisualViewport)),\n { provide: WR_OVERLAY_CONTAINER, useClass: WrOverlayContainer },\n {\n provide: WR_OVERLAY,\n useFactory: (): Overlay => {\n const parent = inject(EnvironmentInjector);\n const container = inject(WR_OVERLAY_CONTAINER);\n\n // Child injector resolves `OverlayContainer` to our subclass and\n // creates a fresh `Overlay` instance bound to it. CDK's own root\n // `Overlay` and `OverlayContainer` are untouched in the parent.\n const child = Injector.create({\n parent,\n providers: [\n { provide: OverlayContainer, useValue: container },\n { provide: Overlay, useClass: Overlay },\n ],\n });\n\n return child.get(Overlay);\n },\n },\n ]);\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { type EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\n\nimport { WR_RESPONSIVE_OVERLAYS, type WrResponsiveOverlaysConfig } from './tokens/wr-responsive-overlays.token';\n\n/**\n * Opt every NGWR overlay into responsive presentation — on viewports at or\n * below `breakpoint`, dialogs / selects / dropdowns and friends slide up as\n * a full-width bottom-sheet instead of a floating panel. Built on the same\n * overlay plumbing, so focus-trap, backdrop and scroll-blocking carry over.\n *\n * Individual components can still opt out (or in) per instance via their\n * `responsive` option.\n *\n * @example\n * ```ts\n * bootstrapApplication(AppComponent, {\n * providers: [provideWrOverlay(), provideWrResponsiveOverlays()],\n * });\n *\n * // Custom breakpoint:\n * provideWrResponsiveOverlays({ breakpoint: 768 });\n * ```\n */\nexport function provideWrResponsiveOverlays(config?: Partial<WrResponsiveOverlaysConfig>): EnvironmentProviders {\n return makeEnvironmentProviders([\n { provide: WR_RESPONSIVE_OVERLAYS, useValue: { breakpoint: config?.breakpoint ?? 640 } },\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-overlay.mjs","sources":["../../../projects/lib/overlay/wr-overlay-close.ts","../../../projects/lib/overlay/wr-follow-direction.ts","../../../projects/lib/overlay/wr-mirror-offsets.ts","../../../projects/lib/overlay/wr-outside-click.ts","../../../projects/lib/overlay/wr-overlay-container.ts","../../../projects/lib/overlay/tokens/wr-overlay.token.ts","../../../projects/lib/overlay/tokens/wr-overlay-container.token.ts","../../../projects/lib/overlay/tokens/wr-responsive-overlays.token.ts","../../../projects/lib/overlay/provide-wr-overlay.ts","../../../projects/lib/overlay/provide-wr-responsive-overlays.ts","../../../projects/lib/overlay/ngwr-overlay.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\nconst SVG_NS = 'http://www.w3.org/2000/svg';\n\n/** The same 24×24 stroked ✕ the rest of the library's chrome draws (alert, toast, lightbox). */\nconst CLOSE_ICON_ATTRS: readonly (readonly [string, string])[] = [\n ['class', 'wr-icon__svg'],\n ['viewBox', '0 0 24 24'],\n ['fill', 'none'],\n ['stroke', 'currentColor'],\n ['stroke-width', '2'],\n ['stroke-linecap', 'round'],\n ['stroke-linejoin', 'round'],\n ['aria-hidden', 'true'],\n];\nconst CLOSE_ICON_PATHS: readonly string[] = ['M18 6 6 18', 'm6 6 12 12'];\n\n/**\n * Builds the ✕ node by node.\n *\n * It was one `innerHTML = CLOSE_ICON`, and the string was a compile-time\n * constant, so it was never an injection risk — it was an AVAILABILITY one.\n * Under `require-trusted-types-for 'script'` an `innerHTML` write throws\n * `TrustedHTML assignment` whatever the string is, and the throw landed after\n * the overlay was on screen: a modal with no ✕, no backdrop subscription and no\n * Escape handler, over the whole application. `createElementNS` is not a\n * Trusted Types sink, so there is nothing left to police.\n */\nfunction createCloseIcon(doc: Document): SVGSVGElement {\n const svg = doc.createElementNS(SVG_NS, 'svg');\n // `setAttribute`, not `.className` — on an SVG element that property is an\n // `SVGAnimatedString` and assigning a string to it silently does nothing.\n for (const [name, value] of CLOSE_ICON_ATTRS) svg.setAttribute(name, value);\n for (const d of CLOSE_ICON_PATHS) {\n const path = doc.createElementNS(SVG_NS, 'path');\n path.setAttribute('d', d);\n svg.appendChild(path);\n }\n return svg;\n}\n\n/**\n * Appends a dismiss (✕) button to a service-opened overlay panel.\n *\n * `WrDialog` and `WrDrawerManager` build their panel around a component the\n * consumer supplies, so there is no template of their own to put a corner button\n * in — they call this instead. Component-driven overlays (`<wr-drawer>`) render\n * the same markup in their template.\n *\n * Uses `host.ownerDocument` rather than the global `document`, so it carries no\n * hidden browser-only assumption; callers still gate on the platform because\n * they have nothing to append to on the server.\n *\n * @param host Panel element the button is appended to (and positioned against).\n * @param className BEM class for the button, e.g. `wr-dialog__close`.\n * @param label Accessible name — already localized by the caller.\n * @param onClose Invoked on click.\n */\nexport function wrAppendOverlayClose(\n host: HTMLElement,\n className: string,\n label: string,\n onClose: () => void\n): HTMLButtonElement {\n const button = host.ownerDocument.createElement('button');\n button.type = 'button';\n button.className = className;\n button.setAttribute('aria-label', label);\n button.appendChild(createCloseIcon(host.ownerDocument));\n button.addEventListener('click', onClose);\n host.appendChild(button);\n return button;\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 type { Direction, Directionality } from '@angular/cdk/bidi';\nimport type { OverlayRef } from '@angular/cdk/overlay';\nimport { type Injector, effect, untracked } from '@angular/core';\n\nimport { Subscription } from 'rxjs';\n\nimport { noop } from 'ngwr/utils';\n\n/**\n * Keep an OPEN overlay on the application's reading direction.\n *\n * The CDK reads the direction ONCE, as a string, when the overlay is created\n * (`overlayConfig.direction ||= directionality.value`), writes it as the host's\n * `dir` on attach, and never looks at it again — `updatePosition()` does not\n * touch it and `setDirection()` is the only thing that does. So an application\n * that flips direction while a panel is open mirrors the page and leaves the\n * panel behind, still `ltr`, still resolving `start` to the left. This site's\n * own LTR/RTL switch is the demonstration: it lives inside a `wr-dropdown`, and\n * the `wr-segmented` it is built from reads `Directionality` live — so the thumb\n * slides to the other slot while the pane around it still renders `ltr`, and\n * parks under the wrong label.\n *\n * Call it once per `OverlayRef`, right after `overlay.create(...)`. The follower\n * ends itself when that overlay detaches or is disposed, so a reopen — which is\n * always a NEW ref in this library — needs a new call, and the returned teardown\n * is only for stopping early.\n *\n * `onDirectionChange` is for the sites whose position LIST is itself\n * direction-dependent (the four that pass their table through\n * {@link wrMirrorOffsets}): it runs with the new direction already on the ref\n * and before the overlay repositions, so the strategy is carrying the mirrored\n * offsets by the time the CDK re-resolves them.\n *\n * SSR-safe: it touches no browser global of its own, and the CDK's position\n * strategies no-op off the browser, so a flip on the server only rewrites the\n * attribute.\n *\n * @param overlayRef The overlay to keep in step, freshly created.\n * @param dir The `Directionality` the caller injected. `null` — an optional\n * inject with no provider, i.e. a bare `TestBed` — means there is nothing\n * ambient to follow and this does nothing at all.\n * @param injector Owns the `valueSignal` watch; the caller's own is right.\n * @param onDirectionChange Re-applies direction-dependent state, e.g.\n * `strategy.withPositions(wrMirrorOffsets(TABLE, direction === 'rtl'))`.\n * @returns Stops following. Idempotent, and unnecessary in the normal case.\n *\n * @example\n * ```ts\n * this.overlayRef = this.overlay.create({ positionStrategy, ... });\n * wrFollowDirection(this.overlayRef, this.dir, this.injector, direction =>\n * positionStrategy.withPositions(\n * wrMirrorOffsets(WR_POPCONFIRM_POSITIONS[this.position()], direction === 'rtl')\n * )\n * );\n * ```\n */\nexport function wrFollowDirection(\n overlayRef: OverlayRef,\n dir: Directionality | null,\n injector: Injector,\n onDirectionChange?: (direction: Direction) => void\n): () => void {\n if (!dir) return noop;\n\n const apply = (next: Direction): void => {\n // Comparing against the REF rather than a direction captured up here does\n // three jobs at once: the watch's mandatory first run is a no-op, a flip\n // that arrives down both channels is applied once, and a same-value write\n // never yanks a panel the user is reading.\n if (next === overlayRef.getDirection()) return;\n\n overlayRef.setDirection(next); // rewrites the host's `dir`; it does NOT reposition\n onDirectionChange?.(next); // the caller re-mirrors its position list here\n overlayRef.updatePosition(); // re-resolves start/end against the direction just set\n };\n\n // Two channels, because they are not the same thing. `valueSignal` is the\n // state — `Directionality.value` is a getter over it, so nothing can change\n // direction without writing it. `change` is an EventEmitter the root instance\n // never emits: it reads the document once at construction and only completes\n // the emitter on destroy, so it belongs to the `[dir]` directive (and to an\n // app, like this site's header, that emits it by hand as a courtesy). Keying\n // on `change` alone would be dead for an app that just writes the signal;\n // keying on the signal alone would ignore the `{ value, change }` test double\n // that a dozen of the library's RTL specs hand their component.\n //\n // `untracked` because of WHERE this is called from: half the call sites open\n // their overlay out of an `effect(() => { if (this.isOpen()) … })`, and\n // `effect()` refuses in dev mode to be created inside a reactive context.\n // Laundering only the CREATION is exactly right — the watch below still\n // depends on `valueSignal` and on nothing else.\n const watch = untracked(() =>\n effect(\n () => {\n // Read as a plain optional function rather than as a `Signal`, because\n // the case being guarded is a double that has no signal at all: falling\n // back to `value` registers no dependency, so the watch simply never\n // re-runs and `change` carries that case on its own.\n const read: (() => Direction) | undefined = dir.valueSignal;\n apply(read ? read() : dir.value);\n },\n { injector }\n )\n );\n\n // rxjs owns the teardown, and an `OverlayRef` is why. Open and close happen in\n // an event handler or an effect, never in an injection context, so the idiom\n // that suggests itself — `takeUntilDestroyed(destroyRef)` — would tie this to\n // the DIRECTIVE's lifetime: a menu opened fifty times would leave fifty\n // followers behind, each pinning a disposed ref. (`WrOutsideClick`'s JSDoc\n // records that same mistake, made at ten call sites.) `detachments()` is the\n // overlay's own lifetime and the one channel every dismissal goes through.\n // And it is not hygiene: `setDirection()` writes through the host element\n // `dispose()` nulls, so a watch that outlives its overlay THROWS on the next\n // flip.\n const teardown = new Subscription();\n const stop = (): void => teardown.unsubscribe();\n\n teardown.add(() => watch.destroy());\n teardown.add(dir.change.subscribe(apply));\n // Both handlers, for the reason `WrOutsideClick` gives: a live ref arrives\n // through `next`, one already disposed before this call has only `complete`\n // left to give.\n teardown.add(overlayRef.detachments().subscribe({ next: stop, complete: stop }));\n\n // `Subscription.unsubscribe()` is a no-op once closed, so the caller's copy of\n // this and the automatic one cannot fight, and calling it twice is free.\n return stop;\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 type { ConnectedPosition } from '@angular/cdk/overlay';\n\n/**\n * Mirror the horizontal offsets of a connected-position list for RTL.\n *\n * The CDK mirrors `originX` / `overlayX` under `dir=\"rtl\"` — a `start` anchor\n * resolves to the origin's right edge — but it does NOT mirror `offsetX`, which\n * it adds to the final PHYSICAL x (`_getOffset` returns `position.offsetX`\n * verbatim). So a position that meant \"sit to the inline-start of the trigger,\n * 8px clear of it\" keeps its `-8` under RTL, where the panel is now on the\n * right: the gap becomes an 8px OVERLAP, and the panel sits on top of the thing\n * it is describing.\n *\n * Nothing in the CDK will do this for us, and the amount is per position, so\n * every ngwr overlay that offsets along the inline axis passes its list through\n * here. `offsetY` is untouched: the block axis does not flip.\n *\n * @example\n * ```ts\n * const dir = inject(Directionality, { optional: true });\n *\n * strategy.withPositions(wrMirrorOffsets(WR_POPOVER_POSITIONS[position], dir?.value === 'rtl'));\n * ```\n */\nexport function wrMirrorOffsets(positions: readonly ConnectedPosition[], isRtl: boolean): ConnectedPosition[] {\n // Copied rather than mutated even when there is nothing to do: the position\n // tables are module-level constants shared by every instance, so handing back\n // the same objects invites a caller to write through them.\n if (!isRtl) return positions.map(position => ({ ...position }));\n\n return positions.map(position => ({\n ...position,\n ...(position.offsetX == null ? {} : { offsetX: -position.offsetX }),\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 type { OverlayRef } from '@angular/cdk/overlay';\nimport { DOCUMENT, isPlatformBrowser } from '@angular/common';\nimport { PLATFORM_ID, Service, inject } from '@angular/core';\n\nimport { Observable, type Subscriber } from 'rxjs';\n\n/** One live subscription to `WrOutsideClick.outsidePointerEvents()`. */\ninterface Watcher {\n readonly overlayRef: OverlayRef;\n readonly subscriber: Subscriber<MouseEvent>;\n}\n\n/**\n * Shadow-piercing `event.target` — `composedPath()[0]` is the real originator\n * when the click started inside a shadow root, where `target` is retargeted to\n * the host.\n */\nfunction eventTarget(event: Event): EventTarget | null {\n if (event.composedPath) {\n try {\n return event.composedPath()[0] ?? event.target;\n } catch {\n /* Detached / synthetic events can throw — fall through to `target`. */\n }\n }\n return event.target;\n}\n\n/** `parent.contains(child)`, but stepping out of shadow roots through their hosts. */\nfunction containsAcrossShadow(parent: Node, child: EventTarget | null): boolean {\n const hasShadowRoot = typeof ShadowRoot !== 'undefined';\n let current = child as Node | null;\n while (current) {\n if (current === parent) return true;\n current = hasShadowRoot && current instanceof ShadowRoot ? current.host : current.parentNode;\n }\n return false;\n}\n\n/**\n * Outside-click source for overlays — a drop-in replacement for\n * `OverlayRef.outsidePointerEvents()`.\n *\n * **Why this exists.** CDK's `OverlayOutsideClickDispatcher` binds its\n * listeners to `document.body`. When page content is shorter than the viewport,\n * a click in the empty space below it targets `<html>` — and `<html>` is\n * `body`'s *parent*, so the event bubbles straight to the document and `body`\n * never sees it. The overlay silently stays open. Listening on the document\n * itself catches both cases, and costs nothing else.\n *\n * Semantics are otherwise identical to the CDK's, deliberately:\n *\n * - Emits on `click` / `auxclick` / `contextmenu`, in the capture phase, and\n * tracks `pointerdown` so a `click` is judged by where the press *started*\n * (a drag that ends outside the pane doesn't count as an outside click).\n * - Walks watchers top-most first and stops at the first one that contains the\n * event, so clicking inside a stacked overlay can't close the ones beneath\n * it (a `wr-select` opened inside a `wr-popover`, say).\n * - Fires for the very click that opened the overlay, which is why every caller\n * also ignores events landing on its own trigger.\n *\n * Registration is per subscription: the document listeners go up with the first\n * watcher and come down with the last, so an app with no open overlay has none.\n * That sentence was aspirational until v11 — see {@link outsidePointerEvents}.\n */\n@Service()\nexport class WrOutsideClick {\n private readonly doc = inject(DOCUMENT);\n private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n /** In attach order — last is top-most. */\n private readonly watchers: Watcher[] = [];\n private cleanup: (() => void) | null = null;\n private pressOrigin: EventTarget | null = null;\n\n /**\n * Emits every `click` / `auxclick` / `contextmenu` that lands outside the\n * given overlay's pane, for as long as the overlay is attached.\n *\n * **It completes when the overlay detaches, and that is load-bearing.** Every\n * one of the ten call sites subscribes inside its own `openOverlay()` and\n * pipes `takeUntilDestroyed(destroyRef)` — a DIRECTIVE lifetime, not an\n * overlay one — and none of them unsubscribes on close, because the natural\n * reading of that idiom is \"this ends with the component\". Without the\n * completion below the teardown never ran: one watcher accumulated per OPEN\n * for the life of the page, each pinning a disposed `OverlayRef` (and through\n * it a detached pane, its portal outlet and their injectors), the four\n * capture-phase document listeners could never come down because\n * `watchers.length` never reached zero, and every click on the page walked a\n * list that only grew. A `mode=\"tooltip\"` popover made it unbounded — one\n * permanent watcher per hover.\n *\n * Completing here rather than fixing ten call sites is deliberate: the next\n * component to open an overlay would have made the same reasonable mistake.\n * It is also what CDK's own `OverlayRef.outsidePointerEvents()` does.\n */\n outsidePointerEvents(overlayRef: OverlayRef): Observable<MouseEvent> {\n return new Observable<MouseEvent>(subscriber => {\n if (!this.isBrowser) return;\n\n const watcher: Watcher = { overlayRef, subscriber };\n this.watchers.push(watcher);\n if (this.watchers.length === 1) this.listen();\n\n // BOTH handlers, and the second one is not defensive padding. `dispose()`\n // emits a detachment and then completes the subject, so a live overlay\n // arrives through `next` — but a ref that was already disposed before\n // anyone subscribed has nothing left to emit and arrives through\n // `complete` alone. Listening for `next` only left exactly the watcher\n // this whole change exists to remove.\n const ended = (): void => subscriber.complete();\n const detached = overlayRef.detachments().subscribe({ next: ended, complete: ended });\n\n return () => {\n detached.unsubscribe();\n const index = this.watchers.indexOf(watcher);\n if (index > -1) this.watchers.splice(index, 1);\n if (!this.watchers.length) this.unlisten();\n };\n });\n }\n\n private readonly onPointerDown = (event: Event): void => {\n this.pressOrigin = eventTarget(event);\n };\n\n private readonly onClick = (event: Event): void => {\n const target = eventTarget(event);\n // `detail > 0` means the click really came from a pointer press. A click\n // activated by Enter or Space carries `detail: 0` and has no `pointerdown`\n // of its own — so trusting a leftover origin there judged it by a press\n // that belonged to something else entirely. A press inside the pane that\n // never produced a click (a drag released off-window, a node removed under\n // the finger, a cancelled touch) survives in `pressOrigin`, and the next\n // keyboard activation anywhere on the page then read as \"inside\": the panel\n // would not close, for keyboard users only.\n const fromPointer = event.type === 'click' && (event as MouseEvent).detail > 0;\n const origin = fromPointer && this.pressOrigin ? this.pressOrigin : target;\n this.pressOrigin = null;\n\n // Snapshot: a watcher that closes on this event unsubscribes synchronously,\n // mutating `watchers` while we're walking it.\n const watchers = this.watchers.slice();\n for (let i = watchers.length - 1; i > -1; i--) {\n const { overlayRef, subscriber } = watchers[i];\n if (!overlayRef.hasAttached()) continue;\n\n const pane = overlayRef.overlayElement;\n if (containsAcrossShadow(pane, target) || containsAcrossShadow(pane, origin)) break;\n\n subscriber.next(event as MouseEvent);\n }\n };\n\n private listen(): void {\n const options: AddEventListenerOptions = { capture: true };\n const doc = this.doc;\n\n doc.addEventListener('pointerdown', this.onPointerDown, options);\n doc.addEventListener('click', this.onClick, options);\n doc.addEventListener('auxclick', this.onClick, options);\n doc.addEventListener('contextmenu', this.onClick, options);\n\n this.cleanup = () => {\n doc.removeEventListener('pointerdown', this.onPointerDown, options);\n doc.removeEventListener('click', this.onClick, options);\n doc.removeEventListener('auxclick', this.onClick, options);\n doc.removeEventListener('contextmenu', this.onClick, options);\n };\n }\n\n private unlisten(): void {\n this.cleanup?.();\n this.cleanup = null;\n this.pressOrigin = null;\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 { OverlayContainer } from '@angular/cdk/overlay';\nimport { Service } from '@angular/core';\n\n/**\n * Custom CDK `OverlayContainer` subclass that tags its DOM element with\n * `.wr-overlay-container` in addition to CDK's own `.cdk-overlay-container`.\n *\n * Why: CDK uses a single overlay container per app — every CDK consumer\n * (this lib, Angular Material, NG-ZORRO, etc.) puts its overlays in the\n * same root element. With this class applied you can scope NGWR-specific\n * overlay styles via the tag, e.g.:\n *\n * ```scss\n * .wr-overlay-container .cdk-overlay-pane { z-index: 1100; }\n * ```\n *\n * It does **not** isolate two libraries that both subclass OverlayContainer\n * — the last provider wins. It does give NGWR overlays a stable CSS hook.\n */\n@Service()\nexport class WrOverlayContainer extends OverlayContainer {\n protected override _createContainer(): void {\n super._createContainer();\n this._containerElement?.classList.add('wr-overlay-container');\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 { Overlay } from '@angular/cdk/overlay';\nimport { InjectionToken, inject } from '@angular/core';\n\n/**\n * Injection token for the CDK `Overlay` service NGWR components should\n * use to open panels.\n *\n * Defaults to CDK's root `Overlay` (shared with every other CDK consumer\n * in the app). Call `provideWrOverlay()` to bind it to an isolated\n * `Overlay` instance backed by a separate `OverlayContainer` — that way\n * NGWR overlays don't share the same DOM root with other libraries.\n *\n * @internal — directives/services inside the lib inject this instead of\n * CDK's `Overlay` directly.\n */\nexport const WR_OVERLAY = new InjectionToken<Overlay>('WR_OVERLAY', {\n providedIn: 'root',\n factory: () => inject(Overlay),\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 { OverlayContainer } from '@angular/cdk/overlay';\nimport { InjectionToken, inject } from '@angular/core';\n\n/**\n * Injection token for the overlay container NGWR components should use.\n *\n * Defaults to CDK's `OverlayContainer` — i.e. the same root element every\n * CDK consumer shares. Call `provideWrOverlay()` to replace it with an\n * isolated instance so NGWR overlays don't collide with other libraries.\n *\n * @internal\n */\nexport const WR_OVERLAY_CONTAINER = new InjectionToken<OverlayContainer>('WR_OVERLAY_CONTAINER', {\n providedIn: 'root',\n factory: () => inject(OverlayContainer),\n});\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { InjectionToken } from '@angular/core';\n\n/** Configuration for responsive (bottom-sheet) overlay presentation. */\ninterface WrResponsiveOverlaysConfig {\n /**\n * Viewport width (CSS px) at or below which overlays present as a\n * bottom-sheet instead of a floating panel. @default 640\n */\n readonly breakpoint: number;\n}\n\n/**\n * When set, overlay services (dialog, select, dropdown, …) present as a\n * slide-up bottom-sheet on viewports at or below `breakpoint`. `null`\n * (the default) keeps every overlay floating. Configure via\n * {@link provideWrResponsiveOverlays}; override per call with a\n * component's `responsive` option.\n *\n * @internal\n */\nconst WR_RESPONSIVE_OVERLAYS = new InjectionToken<WrResponsiveOverlaysConfig | null>('WR_RESPONSIVE_OVERLAYS', {\n factory: () => null,\n});\n\n/**\n * Decide whether an overlay should present as a bottom-sheet for the\n * current viewport.\n *\n * - `responsive === true` — sheet on small viewports regardless of config.\n * - `responsive === false` — never a sheet.\n * - `responsive === undefined` — follow the global config (sheet when\n * {@link provideWrResponsiveOverlays} is configured).\n *\n * SSR-safe: returns `false` when there's no `window`.\n *\n * @internal\n */\nfunction wrPresentAsSheet(responsive: boolean | undefined, config: WrResponsiveOverlaysConfig | null): boolean {\n const enabled = responsive ?? config !== null;\n if (!enabled || typeof window === 'undefined') return false;\n return window.innerWidth <= (config?.breakpoint ?? 640);\n}\n\nexport { WR_RESPONSIVE_OVERLAYS, wrPresentAsSheet };\nexport type { WrResponsiveOverlaysConfig };\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 { Overlay, OverlayContainer } from '@angular/cdk/overlay';\nimport {\n EnvironmentInjector,\n Injector,\n type EnvironmentProviders,\n inject,\n makeEnvironmentProviders,\n provideEnvironmentInitializer,\n} from '@angular/core';\n\nimport { WrVisualViewport } from 'ngwr/platform';\n\nimport { WR_OVERLAY, WR_OVERLAY_CONTAINER } from './tokens';\nimport { WrOverlayContainer } from './wr-overlay-container';\n\n/**\n * Isolates NGWR overlays from other CDK consumers in the app.\n *\n * Without this call, NGWR overlays use CDK's root `Overlay` — they\n * render into the same `.cdk-overlay-container` element as Angular\n * Material, NG-ZORRO, etc. With it, NGWR gets its own `OverlayContainer`\n * (marked `.wr-overlay-container`) **and** its own `Overlay` service\n * instance — so styles, z-index, and lifecycle never collide.\n *\n * It does this by replacing two injection tokens:\n * - `WR_OVERLAY_CONTAINER` → custom `WrOverlayContainer` subclass\n * - `WR_OVERLAY` → a fresh `Overlay` instance built in a child injector\n * that resolves `OverlayContainer` to the custom subclass\n *\n * CDK's own root `Overlay` / `OverlayContainer` are left untouched, so\n * other libraries keep working with their original container.\n *\n * @example\n * ```ts\n * import { provideWrOverlay } from 'ngwr/overlay';\n *\n * bootstrapApplication(AppComponent, {\n * providers: [\n * provideWrOverlay(),\n * ],\n * });\n * ```\n */\nexport function provideWrOverlay(): EnvironmentProviders {\n return makeEnvironmentProviders([\n // Track the visual viewport app-wide so overlay sheets (and the\n // command-palette) can lift above the on-screen keyboard. No-op on the\n // server / in browsers without the API.\n provideEnvironmentInitializer(() => void inject(WrVisualViewport)),\n { provide: WR_OVERLAY_CONTAINER, useClass: WrOverlayContainer },\n {\n provide: WR_OVERLAY,\n useFactory: (): Overlay => {\n const parent = inject(EnvironmentInjector);\n const container = inject(WR_OVERLAY_CONTAINER);\n\n // Child injector resolves `OverlayContainer` to our subclass and\n // creates a fresh `Overlay` instance bound to it. CDK's own root\n // `Overlay` and `OverlayContainer` are untouched in the parent.\n const child = Injector.create({\n parent,\n providers: [\n { provide: OverlayContainer, useValue: container },\n { provide: Overlay, useClass: Overlay },\n ],\n });\n\n return child.get(Overlay);\n },\n },\n ]);\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { type EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\n\nimport { WR_RESPONSIVE_OVERLAYS, type WrResponsiveOverlaysConfig } from './tokens/wr-responsive-overlays.token';\n\n/**\n * Opt every NGWR overlay into responsive presentation — on viewports at or\n * below `breakpoint`, dialogs / selects / dropdowns and friends slide up as\n * a full-width bottom-sheet instead of a floating panel. Built on the same\n * overlay plumbing, so focus-trap, backdrop and scroll-blocking carry over.\n *\n * Individual components can still opt out (or in) per instance via their\n * `responsive` option.\n *\n * @example\n * ```ts\n * bootstrapApplication(AppComponent, {\n * providers: [provideWrOverlay(), provideWrResponsiveOverlays()],\n * });\n *\n * // Custom breakpoint:\n * provideWrResponsiveOverlays({ breakpoint: 768 });\n * ```\n */\nexport function provideWrResponsiveOverlays(config?: Partial<WrResponsiveOverlaysConfig>): EnvironmentProviders {\n return makeEnvironmentProviders([\n { provide: WR_RESPONSIVE_OVERLAYS, useValue: { breakpoint: config?.breakpoint ?? 640 } },\n ]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -45,10 +45,10 @@ class WrPageHeader {
45
45
  * @default false
46
46
  */
47
47
  responsive = input(false, { ...(ngDevMode ? { debugName: "responsive" } : /* istanbul ignore next */ {}), transform: coerceBooleanProperty });
48
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrPageHeader, deps: [], target: i0.ɵɵFactoryTarget.Component });
49
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: WrPageHeader, isStandalone: true, selector: "wr-page-header", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, responsive: { classPropertyName: "responsive", publicName: "responsive", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.wr-page-header--responsive": "responsive()" }, classAttribute: "wr-page-header" }, ngImport: i0, template: "<div class=\"wr-page-header__breadcrumbs\">\n <ng-content select=\"[wrPageHeaderBreadcrumbs]\" />\n</div>\n\n<div class=\"wr-page-header__main\">\n <div class=\"wr-page-header__heading\">\n @if (title()) {\n <h1 class=\"wr-page-header__title\">{{ title() }}</h1>\n }\n @if (subtitle()) {\n <p class=\"wr-page-header__subtitle\">{{ subtitle() }}</p>\n }\n </div>\n <div class=\"wr-page-header__actions\">\n <ng-content select=\"[wrPageHeaderActions]\" />\n </div>\n</div>\n\n<div class=\"wr-page-header__extra\">\n <ng-content select=\"[wrPageHeaderExtra]\" />\n</div>\n", encapsulation: i0.ViewEncapsulation.None });
48
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrPageHeader, deps: [], target: i0.ɵɵFactoryTarget.Component });
49
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: WrPageHeader, isStandalone: true, selector: "wr-page-header", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, responsive: { classPropertyName: "responsive", publicName: "responsive", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.wr-page-header--responsive": "responsive()" }, classAttribute: "wr-page-header" }, ngImport: i0, template: "<div class=\"wr-page-header__breadcrumbs\">\n <ng-content select=\"[wrPageHeaderBreadcrumbs]\" />\n</div>\n\n<div class=\"wr-page-header__main\">\n <div class=\"wr-page-header__heading\">\n @if (title()) {\n <h1 class=\"wr-page-header__title\">{{ title() }}</h1>\n }\n @if (subtitle()) {\n <p class=\"wr-page-header__subtitle\">{{ subtitle() }}</p>\n }\n </div>\n <div class=\"wr-page-header__actions\">\n <ng-content select=\"[wrPageHeaderActions]\" />\n </div>\n</div>\n\n<div class=\"wr-page-header__extra\">\n <ng-content select=\"[wrPageHeaderExtra]\" />\n</div>\n", encapsulation: i0.ViewEncapsulation.None });
50
50
  }
51
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrPageHeader, decorators: [{
51
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrPageHeader, decorators: [{
52
52
  type: Component,
53
53
  args: [{ selector: 'wr-page-header', encapsulation: ViewEncapsulation.None, host: { class: 'wr-page-header', '[class.wr-page-header--responsive]': 'responsive()' }, template: "<div class=\"wr-page-header__breadcrumbs\">\n <ng-content select=\"[wrPageHeaderBreadcrumbs]\" />\n</div>\n\n<div class=\"wr-page-header__main\">\n <div class=\"wr-page-header__heading\">\n @if (title()) {\n <h1 class=\"wr-page-header__title\">{{ title() }}</h1>\n }\n @if (subtitle()) {\n <p class=\"wr-page-header__subtitle\">{{ subtitle() }}</p>\n }\n </div>\n <div class=\"wr-page-header__actions\">\n <ng-content select=\"[wrPageHeaderActions]\" />\n </div>\n</div>\n\n<div class=\"wr-page-header__extra\">\n <ng-content select=\"[wrPageHeaderExtra]\" />\n</div>\n" }]
54
54
  }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], responsive: [{ type: i0.Input, args: [{ isSignal: true, alias: "responsive", required: false }] }] } });
@@ -99,7 +99,32 @@ class WrPagination {
99
99
  /** The nav landmark's own accessible name — was a hardcoded English literal. */
100
100
  navLabel = useI18nText(this.label, 'pagination.label', 'Pagination');
101
101
  /** Internal: total page count. */
102
- totalPages = computed(() => Math.max(1, Math.ceil(this.total() / this.pageSize())), /* @ts-ignore */
102
+ /**
103
+ * A page size that is not a positive number yields ONE page, not `Infinity`.
104
+ *
105
+ * `pageSize` is a `model()`, so Angular offers no `transform` to coerce it and
106
+ * whatever the host writes arrives raw. At 0 the division is `Infinity`,
107
+ * `Math.max(1, …)` keeps it, and the item list below pushes `total` as the
108
+ * last page — so the strip rendered a clickable cell reading "Infinity", and
109
+ * clicking it locked the tab. `NaN` (a `pageSize` bound to an emptied number
110
+ * field) came through untouched for the same reason.
111
+ *
112
+ * One page is the honest answer: a size of zero describes no paging at all.
113
+ * Note this is about `pageSize` and does NOT touch the recorded contract
114
+ * about `total` — pagination still refuses to pull the page DOWN while
115
+ * `total` is at or below zero, because 0 is ambiguous with "still loading".
116
+ */
117
+ usablePageSize = computed(() => {
118
+ const size = this.pageSize();
119
+ if (Number.isFinite(size) && size >= 1)
120
+ return size;
121
+ // Everything on one page. Deliberately not `Infinity`, which gives the
122
+ // right page COUNT by accident and then puts `Infinity` in the range label
123
+ // the moment `page` is above 1.
124
+ return Math.max(1, this.total());
125
+ }, /* @ts-ignore */
126
+ ...(ngDevMode ? [{ debugName: "usablePageSize" }] : /* istanbul ignore next */ []));
127
+ totalPages = computed(() => Math.max(1, Math.ceil(this.total() / this.usablePageSize())), /* @ts-ignore */
103
128
  ...(ngDevMode ? [{ debugName: "totalPages" }] : /* istanbul ignore next */ []));
104
129
  /**
105
130
  * Internal: where the previous arrow goes. Clamped to the end of the valid
@@ -128,8 +153,10 @@ class WrPagination {
128
153
  * concatenation, re-offered as API.
129
154
  */
130
155
  rangeLabel = computed(() => {
131
- const start = this.total() === 0 ? 0 : (this.page() - 1) * this.pageSize() + 1;
132
- const end = Math.min(this.page() * this.pageSize(), this.total());
156
+ // The same guarded size, or the range label reads "1 – NaN of 100".
157
+ const size = this.usablePageSize();
158
+ const start = this.total() === 0 ? 0 : (this.page() - 1) * size + 1;
159
+ const end = Math.min(this.page() * size, this.total());
133
160
  return this.rangeText({
134
161
  from: this.number(start),
135
162
  to: this.number(end),
@@ -294,10 +321,10 @@ class WrPagination {
294
321
  // something the guard covers.
295
322
  this.pageSize.set(next);
296
323
  }
297
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrPagination, deps: [], target: i0.ɵɵFactoryTarget.Component });
298
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.5", type: WrPagination, isStandalone: true, selector: "wr-pagination", inputs: { page: { classPropertyName: "page", publicName: "page", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, total: { classPropertyName: "total", publicName: "total", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, showSizeChanger: { classPropertyName: "showSizeChanger", publicName: "showSizeChanger", isSignal: true, isRequired: false, transformFunction: null }, showTotal: { classPropertyName: "showTotal", publicName: "showTotal", isSignal: true, isRequired: false, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, shape: { classPropertyName: "shape", publicName: "shape", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, responsive: { classPropertyName: "responsive", publicName: "responsive", isSignal: true, isRequired: false, transformFunction: null }, prevLabel: { classPropertyName: "prevLabel", publicName: "prevLabel", isSignal: true, isRequired: false, transformFunction: null }, nextLabel: { classPropertyName: "nextLabel", publicName: "nextLabel", isSignal: true, isRequired: false, transformFunction: null }, itemsPerPageLabel: { classPropertyName: "itemsPerPageLabel", publicName: "itemsPerPageLabel", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { page: "pageChange", pageSize: "pageSizeChange" }, host: { attributes: { "role": "navigation" }, properties: { "class": "classes()", "attr.aria-label": "navLabel()" } }, ngImport: i0, template: "<div class=\"wr-pagination__inner\">\n @if (showTotal()) {\n <span class=\"wr-pagination__total\">{{ rangeLabel() }}</span>\n }\n\n <div class=\"wr-pagination__nav\">\n <!--\n `wr-pagination__nav-btn` exists so the stylesheet can mirror the arrow\n glyph under `dir=\"rtl\"`. A class rather than `:first-child` /\n `:last-child` on the row: those two positions do hold today \u2014 which is why\n the `--square` end caps use them \u2014 but only while the prev button, the\n compact label and the next button all stay unconditional and in this\n order. A mirror keyed to position would follow a reorder, or land on a\n page cell, without a word.\n\n The two `[disabled]` bindings compare against the RANGE (`<= 1`,\n `>= totalPages()`) rather than for equality with its ends. While `total`\n is 0 the guard effect stops enforcing the upper bound, so the page can\n legitimately sit past `totalPages()` \u2014 and `=== totalPages()` reported\n next as enabled there while `goTo` refused the step. Prev is still\n enabled in that state, correctly: `prevPage()` walks it back into range.\n -->\n <wr-btn\n class=\"wr-pagination__nav-btn\"\n [size]=\"size()\"\n outlined\n [attr.aria-label]=\"resolvedPrev()\"\n [disabled]=\"disabled() || page() <= 1\"\n (click)=\"goTo(prevPage())\"\n >\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m12 19-7-7 7-7\" />\n <path d=\"M19 12H5\" />\n </svg>\n </wr-btn>\n\n @for (page of pages(); track $index) {\n @if (page === ellipsis) {\n <span class=\"wr-pagination__ellipsis\">{{ ellipsis }}</span>\n } @else {\n <wr-btn\n class=\"wr-pagination__page\"\n [size]=\"size()\"\n [outlined]=\"!isCurrent(page)\"\n [color]=\"isCurrent(page) ? 'primary' : null\"\n [attr.aria-current]=\"isCurrent(page) ? 'page' : null\"\n [attr.aria-label]=\"goToPage({ page })\"\n [disabled]=\"disabled()\"\n (click)=\"goTo(page)\"\n >\n {{ page }}\n </wr-btn>\n }\n }\n\n <!-- Compact pager \u2014 shown only in responsive mode on a narrow box (CSS). -->\n <span class=\"wr-pagination__current\" aria-hidden=\"true\">{{ compactLabel() }}</span>\n\n <wr-btn\n class=\"wr-pagination__nav-btn\"\n [size]=\"size()\"\n outlined\n [attr.aria-label]=\"resolvedNext()\"\n [disabled]=\"disabled() || page() >= totalPages()\"\n (click)=\"goTo(page() + 1)\"\n >\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M5 12h14\" />\n <path d=\"m12 5 7 7-7 7\" />\n </svg>\n </wr-btn>\n </div>\n\n @if (showSizeChanger()) {\n <!--\n `ariaLabel`, not `[attr.aria-label]`: `<wr-select>`'s host carries no role,\n so an attribute there names nothing and never reaches the `role=\"combobox\"`\n button inside \u2014 the size changer announced itself as the catalog's generic\n \"Select\".\n -->\n <wr-select\n class=\"wr-pagination__size\"\n [ariaLabel]=\"resolvedItemsPerPage()\"\n [disabled]=\"disabled()\"\n [value]=\"pageSize()\"\n (valueChange)=\"onSizeChange($event)\"\n >\n @for (option of pageSizeOptions(); track option) {\n <wr-option [value]=\"option\">{{ perPage({ size: option }) }}</wr-option>\n }\n </wr-select>\n }\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"] }, { kind: "component", type: WrSelect, selector: "wr-select", inputs: ["placeholder", "clearLabel", "ariaLabel", "disabled", "readonly", "rounded", "size", "responsive", "mode", "searchable", "searchQuery", "options", "displayWith", "loader", "serverSearch", "debounceMs", "minChars", "freeText", "virtualScroll", "rowHeight", "viewportHeight", "overscan", "noResultsText", "loadingText", "loading", "separators", "allowDuplicates", "validate", "clearable", "maxItems", "maxTagCount", "value"], outputs: ["searchQueryChange", "searchChange", "valueChange", "touch"] }, { kind: "component", type: WrOption, selector: "wr-option", inputs: ["value", "disabled"] }], encapsulation: i0.ViewEncapsulation.None });
324
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrPagination, deps: [], target: i0.ɵɵFactoryTarget.Component });
325
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: WrPagination, isStandalone: true, selector: "wr-pagination", inputs: { page: { classPropertyName: "page", publicName: "page", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, total: { classPropertyName: "total", publicName: "total", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, showSizeChanger: { classPropertyName: "showSizeChanger", publicName: "showSizeChanger", isSignal: true, isRequired: false, transformFunction: null }, showTotal: { classPropertyName: "showTotal", publicName: "showTotal", isSignal: true, isRequired: false, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, shape: { classPropertyName: "shape", publicName: "shape", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, responsive: { classPropertyName: "responsive", publicName: "responsive", isSignal: true, isRequired: false, transformFunction: null }, prevLabel: { classPropertyName: "prevLabel", publicName: "prevLabel", isSignal: true, isRequired: false, transformFunction: null }, nextLabel: { classPropertyName: "nextLabel", publicName: "nextLabel", isSignal: true, isRequired: false, transformFunction: null }, itemsPerPageLabel: { classPropertyName: "itemsPerPageLabel", publicName: "itemsPerPageLabel", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { page: "pageChange", pageSize: "pageSizeChange" }, host: { attributes: { "role": "navigation" }, properties: { "class": "classes()", "attr.aria-label": "navLabel()" } }, ngImport: i0, template: "<div class=\"wr-pagination__inner\">\n @if (showTotal()) {\n <span class=\"wr-pagination__total\">{{ rangeLabel() }}</span>\n }\n\n <div class=\"wr-pagination__nav\">\n <!--\n `wr-pagination__nav-btn` exists so the stylesheet can mirror the arrow\n glyph under `dir=\"rtl\"`. A class rather than `:first-child` /\n `:last-child` on the row: those two positions do hold today \u2014 which is why\n the `--square` end caps use them \u2014 but only while the prev button, the\n compact label and the next button all stay unconditional and in this\n order. A mirror keyed to position would follow a reorder, or land on a\n page cell, without a word.\n\n The two `[disabled]` bindings compare against the RANGE (`<= 1`,\n `>= totalPages()`) rather than for equality with its ends. While `total`\n is 0 the guard effect stops enforcing the upper bound, so the page can\n legitimately sit past `totalPages()` \u2014 and `=== totalPages()` reported\n next as enabled there while `goTo` refused the step. Prev is still\n enabled in that state, correctly: `prevPage()` walks it back into range.\n -->\n <wr-btn\n class=\"wr-pagination__nav-btn\"\n [size]=\"size()\"\n outlined\n [attr.aria-label]=\"resolvedPrev()\"\n [disabled]=\"disabled() || page() <= 1\"\n (click)=\"goTo(prevPage())\"\n >\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m12 19-7-7 7-7\" />\n <path d=\"M19 12H5\" />\n </svg>\n </wr-btn>\n\n @for (page of pages(); track $index) {\n @if (page === ellipsis) {\n <span class=\"wr-pagination__ellipsis\">{{ ellipsis }}</span>\n } @else {\n <wr-btn\n class=\"wr-pagination__page\"\n [size]=\"size()\"\n [outlined]=\"!isCurrent(page)\"\n [color]=\"isCurrent(page) ? 'primary' : null\"\n [attr.aria-current]=\"isCurrent(page) ? 'page' : null\"\n [attr.aria-label]=\"goToPage({ page })\"\n [disabled]=\"disabled()\"\n (click)=\"goTo(page)\"\n >\n {{ page }}\n </wr-btn>\n }\n }\n\n <!-- Compact pager \u2014 shown only in responsive mode on a narrow box (CSS). -->\n <span class=\"wr-pagination__current\" aria-hidden=\"true\">{{ compactLabel() }}</span>\n\n <wr-btn\n class=\"wr-pagination__nav-btn\"\n [size]=\"size()\"\n outlined\n [attr.aria-label]=\"resolvedNext()\"\n [disabled]=\"disabled() || page() >= totalPages()\"\n (click)=\"goTo(page() + 1)\"\n >\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M5 12h14\" />\n <path d=\"m12 5 7 7-7 7\" />\n </svg>\n </wr-btn>\n </div>\n\n @if (showSizeChanger()) {\n <!--\n `ariaLabel`, not `[attr.aria-label]`: `<wr-select>`'s host carries no role,\n so an attribute there names nothing and never reaches the `role=\"combobox\"`\n button inside \u2014 the size changer announced itself as the catalog's generic\n \"Select\".\n -->\n <wr-select\n class=\"wr-pagination__size\"\n [ariaLabel]=\"resolvedItemsPerPage()\"\n [disabled]=\"disabled()\"\n [value]=\"pageSize()\"\n (valueChange)=\"onSizeChange($event)\"\n >\n @for (option of pageSizeOptions(); track option) {\n <wr-option [value]=\"option\">{{ perPage({ size: option }) }}</wr-option>\n }\n </wr-select>\n }\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"] }, { kind: "component", type: WrSelect, selector: "wr-select", inputs: ["placeholder", "clearLabel", "ariaLabel", "disabled", "readonly", "rounded", "size", "responsive", "mode", "searchable", "searchQuery", "options", "displayWith", "loader", "serverSearch", "debounceMs", "minChars", "freeText", "virtualScroll", "rowHeight", "viewportHeight", "overscan", "noResultsText", "loadingText", "loading", "separators", "allowDuplicates", "validate", "clearable", "maxItems", "maxTagCount", "value"], outputs: ["searchQueryChange", "searchChange", "valueChange", "touch"] }, { kind: "component", type: WrOption, selector: "wr-option", inputs: ["value", "disabled"] }], encapsulation: i0.ViewEncapsulation.None });
299
326
  }
300
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrPagination, decorators: [{
327
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrPagination, decorators: [{
301
328
  type: Component,
302
329
  args: [{ selector: 'wr-pagination', encapsulation: ViewEncapsulation.None, host: { '[class]': 'classes()', role: 'navigation', '[attr.aria-label]': 'navLabel()' }, imports: [WrButton, WrSelect, WrOption], template: "<div class=\"wr-pagination__inner\">\n @if (showTotal()) {\n <span class=\"wr-pagination__total\">{{ rangeLabel() }}</span>\n }\n\n <div class=\"wr-pagination__nav\">\n <!--\n `wr-pagination__nav-btn` exists so the stylesheet can mirror the arrow\n glyph under `dir=\"rtl\"`. A class rather than `:first-child` /\n `:last-child` on the row: those two positions do hold today \u2014 which is why\n the `--square` end caps use them \u2014 but only while the prev button, the\n compact label and the next button all stay unconditional and in this\n order. A mirror keyed to position would follow a reorder, or land on a\n page cell, without a word.\n\n The two `[disabled]` bindings compare against the RANGE (`<= 1`,\n `>= totalPages()`) rather than for equality with its ends. While `total`\n is 0 the guard effect stops enforcing the upper bound, so the page can\n legitimately sit past `totalPages()` \u2014 and `=== totalPages()` reported\n next as enabled there while `goTo` refused the step. Prev is still\n enabled in that state, correctly: `prevPage()` walks it back into range.\n -->\n <wr-btn\n class=\"wr-pagination__nav-btn\"\n [size]=\"size()\"\n outlined\n [attr.aria-label]=\"resolvedPrev()\"\n [disabled]=\"disabled() || page() <= 1\"\n (click)=\"goTo(prevPage())\"\n >\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m12 19-7-7 7-7\" />\n <path d=\"M19 12H5\" />\n </svg>\n </wr-btn>\n\n @for (page of pages(); track $index) {\n @if (page === ellipsis) {\n <span class=\"wr-pagination__ellipsis\">{{ ellipsis }}</span>\n } @else {\n <wr-btn\n class=\"wr-pagination__page\"\n [size]=\"size()\"\n [outlined]=\"!isCurrent(page)\"\n [color]=\"isCurrent(page) ? 'primary' : null\"\n [attr.aria-current]=\"isCurrent(page) ? 'page' : null\"\n [attr.aria-label]=\"goToPage({ page })\"\n [disabled]=\"disabled()\"\n (click)=\"goTo(page)\"\n >\n {{ page }}\n </wr-btn>\n }\n }\n\n <!-- Compact pager \u2014 shown only in responsive mode on a narrow box (CSS). -->\n <span class=\"wr-pagination__current\" aria-hidden=\"true\">{{ compactLabel() }}</span>\n\n <wr-btn\n class=\"wr-pagination__nav-btn\"\n [size]=\"size()\"\n outlined\n [attr.aria-label]=\"resolvedNext()\"\n [disabled]=\"disabled() || page() >= totalPages()\"\n (click)=\"goTo(page() + 1)\"\n >\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M5 12h14\" />\n <path d=\"m12 5 7 7-7 7\" />\n </svg>\n </wr-btn>\n </div>\n\n @if (showSizeChanger()) {\n <!--\n `ariaLabel`, not `[attr.aria-label]`: `<wr-select>`'s host carries no role,\n so an attribute there names nothing and never reaches the `role=\"combobox\"`\n button inside \u2014 the size changer announced itself as the catalog's generic\n \"Select\".\n -->\n <wr-select\n class=\"wr-pagination__size\"\n [ariaLabel]=\"resolvedItemsPerPage()\"\n [disabled]=\"disabled()\"\n [value]=\"pageSize()\"\n (valueChange)=\"onSizeChange($event)\"\n >\n @for (option of pageSizeOptions(); track option) {\n <wr-option [value]=\"option\">{{ perPage({ size: option }) }}</wr-option>\n }\n </wr-select>\n }\n</div>\n" }]
303
330
  }], ctorParameters: () => [], propDecorators: { page: [{ type: i0.Input, args: [{ isSignal: true, alias: "page", required: false }] }, { type: i0.Output, args: ["pageChange"] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }, { type: i0.Output, args: ["pageSizeChange"] }], total: [{ type: i0.Input, args: [{ isSignal: true, alias: "total", required: false }] }], pageSizeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSizeOptions", required: false }] }], showSizeChanger: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSizeChanger", required: false }] }], showTotal: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTotal", required: false }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], responsive: [{ type: i0.Input, args: [{ isSignal: true, alias: "responsive", required: false }] }], prevLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "prevLabel", required: false }] }], nextLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "nextLabel", required: false }] }], itemsPerPageLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemsPerPageLabel", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }] } });
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-pagination.mjs","sources":["../../../projects/lib/pagination/pagination.ts","../../../projects/lib/pagination/pagination.html","../../../projects/lib/pagination/ngwr-pagination.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { Component, LOCALE_ID, ViewEncapsulation, computed, effect, inject, input, model } from '@angular/core';\n\nimport { WrButton } from 'ngwr/button';\nimport { useI18nFormatter, useI18nText } from 'ngwr/i18n';\nimport { WrOption, WrSelect } from 'ngwr/select';\nimport { numAttr } from 'ngwr/utils';\n\nimport type { WrPaginationAlign, WrPaginationShape, WrPaginationSize } from './interfaces';\n\nconst ELLIPSIS = '…' as const;\ntype PageEntry = number | typeof ELLIPSIS;\n\n/**\n * Numbered page navigator with optional total / page-size controls.\n *\n * Two-way binds `page` and `pageSize` via signal `model()` inputs.\n *\n * @example\n * ```html\n * <wr-pagination\n * [total]=\"120\"\n * [(page)]=\"page\"\n * [(pageSize)]=\"size\"\n * showTotal\n * showSizeChanger\n * />\n * ```\n *\n * @see https://ngwr.dev/reference/components/pagination\n */\n@Component({\n selector: 'wr-pagination',\n templateUrl: './pagination.html',\n encapsulation: ViewEncapsulation.None,\n host: { '[class]': 'classes()', role: 'navigation', '[attr.aria-label]': 'navLabel()' },\n imports: [WrButton, WrSelect, WrOption],\n})\nexport class WrPagination {\n /**\n * Currently displayed page (1-based). Two-way bindable.\n *\n * `page` rather than `currentPage` since v14, so this and `<wr-table>` — which\n * renders one of these in its own footer — spell the two concepts they share\n * one way each. It also names the output: a `model()` called `X` forces\n * `(XChange)`, so the old name produced `(currentPageChange)` against the\n * table's `(pageChange)`.\n */\n readonly page = model<number>(1);\n\n /** Items per page. Two-way bindable. */\n readonly pageSize = model<number>(10);\n\n /** Total item count across all pages. */\n readonly total = input(0, { transform: numAttr(0) });\n\n /** Options shown in the page-size dropdown. */\n readonly pageSizeOptions = input<readonly number[]>([10, 20, 50, 100]);\n\n /** Render the page-size dropdown. @default false */\n readonly showSizeChanger = input(false, { transform: coerceBooleanProperty });\n\n /** Render the \"X–Y of Z\" total label. @default false */\n readonly showTotal = input(false, { transform: coerceBooleanProperty });\n\n /** Horizontal alignment. @default 'start' */\n readonly align = input<WrPaginationAlign>('start');\n\n /** Size variant — cascades to every internal button. @default 'sm' */\n readonly size = input<WrPaginationSize>('sm');\n\n /** Cell corner treatment. @default 'rounded' */\n readonly shape = input<WrPaginationShape>('rounded');\n\n /** Disable interaction. @default false */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n /**\n * Collapse to a compact `‹ page / total ›` pager when the control's own box\n * is too narrow for the full numbered strip (a container query on its own\n * width, not the viewport). @default false\n */\n readonly responsive = input(false, { transform: coerceBooleanProperty });\n\n /** Previous-page button aria-label. Falls back to `pagination.prev`. */\n readonly prevLabel = input<string | null>(null);\n\n /** Next-page button aria-label. Falls back to `pagination.next`. */\n readonly nextLabel = input<string | null>(null);\n\n /** \"Items per page\" label. Falls back to `pagination.itemsPerPage`. */\n readonly itemsPerPageLabel = input<string | null>(null);\n\n /** Accessible name for the `role=\"navigation\"` host. Falls back to `pagination.label`. */\n readonly label = input<string | null>(null);\n\n /** Resolved labels. */\n protected readonly resolvedPrev = useI18nText(this.prevLabel, 'pagination.prev', 'Previous page');\n protected readonly resolvedNext = useI18nText(this.nextLabel, 'pagination.next', 'Next page');\n protected readonly resolvedItemsPerPage = useI18nText(\n this.itemsPerPageLabel,\n 'pagination.itemsPerPage',\n 'Items per page'\n );\n\n /**\n * Page-size option text — interpolates `{{size}}`. Was the template literal\n * `{{ option }} / page`, which no catalog could reach, so a Russian UI read\n * \"25 / page\".\n */\n protected readonly perPage = useI18nFormatter('pagination.perPage', '{{size}} / page');\n\n /** Per-page-button aria-label — interpolates `{{page}}`. */\n protected readonly goToPage = useI18nFormatter('pagination.goToPage', 'Go to page {{page}}');\n\n /** The nav landmark's own accessible name — was a hardcoded English literal. */\n protected readonly navLabel = useI18nText(this.label, 'pagination.label', 'Pagination');\n\n /** Internal: total page count. */\n protected readonly totalPages = computed(() => Math.max(1, Math.ceil(this.total() / this.pageSize())));\n\n /**\n * Internal: where the previous arrow goes. Clamped to the end of the valid\n * range rather than being a plain `page() - 1`, because the page can\n * legitimately sit past that end while `total` is 0 (see the guard effect).\n * From page 5 of one page, `goTo(4)` is refused as out of range, so the arrow\n * was enabled and did nothing — and under `responsive` on a narrow box the\n * numbered cells are hidden by a container query, which left no way back at\n * all. `Math.min` only ever moves the target INWARD, so `goTo`'s own\n * past-the-end refusal keeps working as the backstop it is.\n */\n protected readonly prevPage = computed(() => Math.min(this.page() - 1, this.totalPages()));\n\n /**\n * Internal: the \"1–10 of 235\" line, as ONE catalog template.\n *\n * It used to be `` `${start}-${end} ${of} ${total}` ``, which localised the\n * word in the middle and nothing else: the ASCII hyphen between the bounds and\n * the operand order were both frozen in TypeScript, so ja-JP and ar-SA got\n * English word order and no language could change the range separator. The\n * three numbers go through `Intl.NumberFormat` for the same reason the total\n * beside them does — a five-figure total needs the locale's grouping, and\n * ar-SA needs its own digits.\n *\n * The `ofLabel` input is gone with it: an input for the middle word is the\n * concatenation, re-offered as API.\n */\n protected readonly rangeLabel = computed(() => {\n const start = this.total() === 0 ? 0 : (this.page() - 1) * this.pageSize() + 1;\n const end = Math.min(this.page() * this.pageSize(), this.total());\n return this.rangeText({\n from: this.number(start),\n to: this.number(end),\n total: this.number(this.total()),\n });\n });\n\n /** Internal: the compact pager's `1 / 24`, likewise a catalog template. */\n protected readonly compactLabel = computed(() =>\n this.compactText({ current: this.number(this.page()), total: this.number(this.totalPages()) })\n );\n\n private readonly rangeText = useI18nFormatter('pagination.range', '{{from}}–{{to}} of {{total}}');\n private readonly compactText = useI18nFormatter('pagination.compact', '{{current}} / {{total}}');\n\n private readonly locale = inject(LOCALE_ID);\n\n /**\n * Grouped per `LOCALE_ID`. Only the range and the compact pager go through\n * this — a page NUMBER on a button is an identifier, and `1,024` on a button\n * reads as two things.\n */\n private number(value: number): string {\n return new Intl.NumberFormat(this.locale).format(value);\n }\n\n /**\n * Internal: page list with ellipses. Window of 7 visible page slots.\n *\n * 1 … 5 6 [7] 8 9 … 20\n */\n protected readonly pages = computed<readonly PageEntry[]>(() => {\n const total = this.totalPages();\n const current = this.page();\n\n if (total <= 7) {\n return Array.from({ length: total }, (_, i) => i + 1);\n }\n\n const items: PageEntry[] = [1];\n if (current > 4) items.push(ELLIPSIS);\n\n let start: number;\n let end: number;\n if (current <= 4) {\n start = 2;\n end = 5;\n } else if (current >= total - 3) {\n start = total - 4;\n end = total - 1;\n } else {\n start = current - 2;\n end = current + 2;\n }\n\n for (let i = start; i <= end; i++) items.push(i);\n if (current < total - 3) items.push(ELLIPSIS);\n if (end !== total) items.push(total);\n\n return items;\n });\n\n protected readonly ellipsis = ELLIPSIS;\n\n protected readonly classes = computed(() => {\n const parts = [\n 'wr-pagination',\n `wr-pagination--${this.align()}`,\n `wr-pagination--${this.size()}`,\n `wr-pagination--${this.shape()}`,\n ];\n if (this.disabled()) parts.push('wr-pagination--disabled');\n if (this.responsive()) parts.push('wr-pagination--responsive');\n return parts.join(' ');\n });\n\n protected isCurrent(page: number): boolean {\n return this.page() === page;\n }\n\n protected goTo(page: number | typeof ELLIPSIS): void {\n if (typeof page !== 'number') return;\n if (this.disabled() || page < 1 || page > this.totalPages() || page === this.page()) return;\n this.page.set(page);\n }\n\n /**\n * `wr-select` carries an `unknown` value by design, so the size arrives\n * untyped and is narrowed here. It used to arrive as `any` through\n * `[ngModel]`, which hid the coercion rather than removing the need for it.\n */\n constructor() {\n // `page` is a plain `model` — a `model()` takes no transform — so a\n // shrinking `total` and a host `[(page)]` write both land in it\n // unchecked. The guard used to read and write the page inside `untracked()`\n // and pull DOWNWARDS only, so it fired when `total` / `pageSize` moved and\n // never when the host wrote: past the end no cell carries `aria-current`,\n // the arrow at that end stays enabled and inert (`goTo` refuses the step\n // rather than correcting the stored page), and below 1 `rangeLabel()` counts\n // backwards (\"-9-0 of 120\"). Two-sided and tracked, the same shape\n // `wr-stepper` and `wr-carousel` use for their own host-owned `model()`.\n //\n // Only the UPPER bound is conditional. A `total` at or below 0 is the one\n // value where pulling the page down is destructive rather than cosmetic:\n // there is no `loading` input, so 0 is genuinely ambiguous between \"the\n // list is empty\" and \"the page is still in flight\", and the second is the\n // ordinary state of a server-paged host — Angular's `resource` drops its\n // value whenever the params change, and a params function returning an\n // object literal is never reference-equal, so `total` reads 0 between the\n // click and the response. `totalPages()` is 1 there, so the guard pulled\n // every page above the first back to 1 and emitted a `pageChange`\n // the host could not tell from a click: the pager could not leave page 1,\n // and each click cost two events. A negative `total` is folded into the\n // same branch because it is as meaningless as a zero one.\n //\n // The LOWER bound is unconditional, and gating it on `total` was a mistake\n // in the first cut of this fix: no value of `total` makes page 0 correct,\n // and while it was skipped a host write of -3 survived — `rangeLabel()`\n // guards `start` for an empty total and not `end`, so it read \"0--30 of 0\",\n // and the compact pager read \"-3 / 1\". It is written as one expression\n // rather than an early return so the effect depends on `page()` and\n // `total()` on every run, whichever branch decides the result.\n //\n // What IS still given up while `total` is 0 and the held page is past the\n // first: no cell carries `aria-current`, because `pages` renders the single\n // page and that is not the page the host holds. `rangeLabel()` is not in\n // that list — it already special-cases an empty total and reads \"0-0 of 0\".\n // Nor are the arrows: they compare against the RANGE rather than its ends\n // (see the template), so past the end next renders disabled and prev stays\n // enabled and steps back INTO range via `prevPage`. That is a change from\n // the \"enabled and inert\" behaviour described above, which this component\n // used to accept at both ends.\n effect(() => {\n const page = this.page();\n const floored = Math.max(1, page);\n const clamped = this.total() <= 0 ? floored : Math.min(floored, this.totalPages());\n if (clamped !== page) this.page.set(clamped);\n });\n }\n\n protected onSizeChange(size: unknown): void {\n const next = Number(size);\n if (this.disabled() || !Number.isFinite(next) || next <= 0 || next === this.pageSize()) return;\n // The size and nothing else. This used to clamp the page against the new\n // size too, and it read a value that was already superseded: `pageSize.set`\n // emits `pageSizeChange` synchronously, so by the following statement the\n // host has run its own policy — most tables reset to the first page — and\n // that write has not reached the model yet, it arrives on the next binding\n // pass. So the clamp computed a cap from the PRE-change page and wrote the\n // result over the host's decision: from page 6 at size 10, choosing 25\n // emitted `pageChange(5)` on top of the host's reset to 1, which the\n // host cannot tell from a navigation, and a second request went out. The\n // guard effect in the constructor takes it over and runs once the bindings\n // have settled, so it clamps the page the host actually wants.\n //\n // For a SETTLED `total` that is the whole story. For the server-paged host\n // this fix exists for it is not: the size change invalidates the payload\n // too, so `total` reads 0 and the guard returns early. Measured, from page\n // 6 at size 10 choosing 25 with a host that does not reset — in flight:\n // `navigations []`, page 6, total 0; after settle: `navigations [5]`, page\n // 5. So a non-resetting host issues one doomed request for a page that no\n // longer exists and is corrected only when the answer lands. That is an\n // accepted cost of refusing to write back from transient state, not\n // something the guard covers.\n this.pageSize.set(next);\n }\n}\n","<div class=\"wr-pagination__inner\">\n @if (showTotal()) {\n <span class=\"wr-pagination__total\">{{ rangeLabel() }}</span>\n }\n\n <div class=\"wr-pagination__nav\">\n <!--\n `wr-pagination__nav-btn` exists so the stylesheet can mirror the arrow\n glyph under `dir=\"rtl\"`. A class rather than `:first-child` /\n `:last-child` on the row: those two positions do hold today — which is why\n the `--square` end caps use them — but only while the prev button, the\n compact label and the next button all stay unconditional and in this\n order. A mirror keyed to position would follow a reorder, or land on a\n page cell, without a word.\n\n The two `[disabled]` bindings compare against the RANGE (`<= 1`,\n `>= totalPages()`) rather than for equality with its ends. While `total`\n is 0 the guard effect stops enforcing the upper bound, so the page can\n legitimately sit past `totalPages()` — and `=== totalPages()` reported\n next as enabled there while `goTo` refused the step. Prev is still\n enabled in that state, correctly: `prevPage()` walks it back into range.\n -->\n <wr-btn\n class=\"wr-pagination__nav-btn\"\n [size]=\"size()\"\n outlined\n [attr.aria-label]=\"resolvedPrev()\"\n [disabled]=\"disabled() || page() <= 1\"\n (click)=\"goTo(prevPage())\"\n >\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m12 19-7-7 7-7\" />\n <path d=\"M19 12H5\" />\n </svg>\n </wr-btn>\n\n @for (page of pages(); track $index) {\n @if (page === ellipsis) {\n <span class=\"wr-pagination__ellipsis\">{{ ellipsis }}</span>\n } @else {\n <wr-btn\n class=\"wr-pagination__page\"\n [size]=\"size()\"\n [outlined]=\"!isCurrent(page)\"\n [color]=\"isCurrent(page) ? 'primary' : null\"\n [attr.aria-current]=\"isCurrent(page) ? 'page' : null\"\n [attr.aria-label]=\"goToPage({ page })\"\n [disabled]=\"disabled()\"\n (click)=\"goTo(page)\"\n >\n {{ page }}\n </wr-btn>\n }\n }\n\n <!-- Compact pager — shown only in responsive mode on a narrow box (CSS). -->\n <span class=\"wr-pagination__current\" aria-hidden=\"true\">{{ compactLabel() }}</span>\n\n <wr-btn\n class=\"wr-pagination__nav-btn\"\n [size]=\"size()\"\n outlined\n [attr.aria-label]=\"resolvedNext()\"\n [disabled]=\"disabled() || page() >= totalPages()\"\n (click)=\"goTo(page() + 1)\"\n >\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M5 12h14\" />\n <path d=\"m12 5 7 7-7 7\" />\n </svg>\n </wr-btn>\n </div>\n\n @if (showSizeChanger()) {\n <!--\n `ariaLabel`, not `[attr.aria-label]`: `<wr-select>`'s host carries no role,\n so an attribute there names nothing and never reaches the `role=\"combobox\"`\n button inside — the size changer announced itself as the catalog's generic\n \"Select\".\n -->\n <wr-select\n class=\"wr-pagination__size\"\n [ariaLabel]=\"resolvedItemsPerPage()\"\n [disabled]=\"disabled()\"\n [value]=\"pageSize()\"\n (valueChange)=\"onSizeChange($event)\"\n >\n @for (option of pageSizeOptions(); track option) {\n <wr-option [value]=\"option\">{{ perPage({ size: option }) }}</wr-option>\n }\n </wr-select>\n }\n</div>\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-pagination.mjs","sources":["../../../projects/lib/pagination/pagination.ts","../../../projects/lib/pagination/pagination.html","../../../projects/lib/pagination/ngwr-pagination.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { Component, LOCALE_ID, ViewEncapsulation, computed, effect, inject, input, model } from '@angular/core';\n\nimport { WrButton } from 'ngwr/button';\nimport { useI18nFormatter, useI18nText } from 'ngwr/i18n';\nimport { WrOption, WrSelect } from 'ngwr/select';\nimport { numAttr } from 'ngwr/utils';\n\nimport type { WrPaginationAlign, WrPaginationShape, WrPaginationSize } from './interfaces';\n\nconst ELLIPSIS = '…' as const;\ntype PageEntry = number | typeof ELLIPSIS;\n\n/**\n * Numbered page navigator with optional total / page-size controls.\n *\n * Two-way binds `page` and `pageSize` via signal `model()` inputs.\n *\n * @example\n * ```html\n * <wr-pagination\n * [total]=\"120\"\n * [(page)]=\"page\"\n * [(pageSize)]=\"size\"\n * showTotal\n * showSizeChanger\n * />\n * ```\n *\n * @see https://ngwr.dev/reference/components/pagination\n */\n@Component({\n selector: 'wr-pagination',\n templateUrl: './pagination.html',\n encapsulation: ViewEncapsulation.None,\n host: { '[class]': 'classes()', role: 'navigation', '[attr.aria-label]': 'navLabel()' },\n imports: [WrButton, WrSelect, WrOption],\n})\nexport class WrPagination {\n /**\n * Currently displayed page (1-based). Two-way bindable.\n *\n * `page` rather than `currentPage` since v14, so this and `<wr-table>` — which\n * renders one of these in its own footer — spell the two concepts they share\n * one way each. It also names the output: a `model()` called `X` forces\n * `(XChange)`, so the old name produced `(currentPageChange)` against the\n * table's `(pageChange)`.\n */\n readonly page = model<number>(1);\n\n /** Items per page. Two-way bindable. */\n readonly pageSize = model<number>(10);\n\n /** Total item count across all pages. */\n readonly total = input(0, { transform: numAttr(0) });\n\n /** Options shown in the page-size dropdown. */\n readonly pageSizeOptions = input<readonly number[]>([10, 20, 50, 100]);\n\n /** Render the page-size dropdown. @default false */\n readonly showSizeChanger = input(false, { transform: coerceBooleanProperty });\n\n /** Render the \"X–Y of Z\" total label. @default false */\n readonly showTotal = input(false, { transform: coerceBooleanProperty });\n\n /** Horizontal alignment. @default 'start' */\n readonly align = input<WrPaginationAlign>('start');\n\n /** Size variant — cascades to every internal button. @default 'sm' */\n readonly size = input<WrPaginationSize>('sm');\n\n /** Cell corner treatment. @default 'rounded' */\n readonly shape = input<WrPaginationShape>('rounded');\n\n /** Disable interaction. @default false */\n readonly disabled = input(false, { transform: coerceBooleanProperty });\n\n /**\n * Collapse to a compact `‹ page / total ›` pager when the control's own box\n * is too narrow for the full numbered strip (a container query on its own\n * width, not the viewport). @default false\n */\n readonly responsive = input(false, { transform: coerceBooleanProperty });\n\n /** Previous-page button aria-label. Falls back to `pagination.prev`. */\n readonly prevLabel = input<string | null>(null);\n\n /** Next-page button aria-label. Falls back to `pagination.next`. */\n readonly nextLabel = input<string | null>(null);\n\n /** \"Items per page\" label. Falls back to `pagination.itemsPerPage`. */\n readonly itemsPerPageLabel = input<string | null>(null);\n\n /** Accessible name for the `role=\"navigation\"` host. Falls back to `pagination.label`. */\n readonly label = input<string | null>(null);\n\n /** Resolved labels. */\n protected readonly resolvedPrev = useI18nText(this.prevLabel, 'pagination.prev', 'Previous page');\n protected readonly resolvedNext = useI18nText(this.nextLabel, 'pagination.next', 'Next page');\n protected readonly resolvedItemsPerPage = useI18nText(\n this.itemsPerPageLabel,\n 'pagination.itemsPerPage',\n 'Items per page'\n );\n\n /**\n * Page-size option text — interpolates `{{size}}`. Was the template literal\n * `{{ option }} / page`, which no catalog could reach, so a Russian UI read\n * \"25 / page\".\n */\n protected readonly perPage = useI18nFormatter('pagination.perPage', '{{size}} / page');\n\n /** Per-page-button aria-label — interpolates `{{page}}`. */\n protected readonly goToPage = useI18nFormatter('pagination.goToPage', 'Go to page {{page}}');\n\n /** The nav landmark's own accessible name — was a hardcoded English literal. */\n protected readonly navLabel = useI18nText(this.label, 'pagination.label', 'Pagination');\n\n /** Internal: total page count. */\n /**\n * A page size that is not a positive number yields ONE page, not `Infinity`.\n *\n * `pageSize` is a `model()`, so Angular offers no `transform` to coerce it and\n * whatever the host writes arrives raw. At 0 the division is `Infinity`,\n * `Math.max(1, …)` keeps it, and the item list below pushes `total` as the\n * last page — so the strip rendered a clickable cell reading \"Infinity\", and\n * clicking it locked the tab. `NaN` (a `pageSize` bound to an emptied number\n * field) came through untouched for the same reason.\n *\n * One page is the honest answer: a size of zero describes no paging at all.\n * Note this is about `pageSize` and does NOT touch the recorded contract\n * about `total` — pagination still refuses to pull the page DOWN while\n * `total` is at or below zero, because 0 is ambiguous with \"still loading\".\n */\n private readonly usablePageSize = computed(() => {\n const size = this.pageSize();\n if (Number.isFinite(size) && size >= 1) return size;\n // Everything on one page. Deliberately not `Infinity`, which gives the\n // right page COUNT by accident and then puts `Infinity` in the range label\n // the moment `page` is above 1.\n return Math.max(1, this.total());\n });\n\n protected readonly totalPages = computed(() => Math.max(1, Math.ceil(this.total() / this.usablePageSize())));\n\n /**\n * Internal: where the previous arrow goes. Clamped to the end of the valid\n * range rather than being a plain `page() - 1`, because the page can\n * legitimately sit past that end while `total` is 0 (see the guard effect).\n * From page 5 of one page, `goTo(4)` is refused as out of range, so the arrow\n * was enabled and did nothing — and under `responsive` on a narrow box the\n * numbered cells are hidden by a container query, which left no way back at\n * all. `Math.min` only ever moves the target INWARD, so `goTo`'s own\n * past-the-end refusal keeps working as the backstop it is.\n */\n protected readonly prevPage = computed(() => Math.min(this.page() - 1, this.totalPages()));\n\n /**\n * Internal: the \"1–10 of 235\" line, as ONE catalog template.\n *\n * It used to be `` `${start}-${end} ${of} ${total}` ``, which localised the\n * word in the middle and nothing else: the ASCII hyphen between the bounds and\n * the operand order were both frozen in TypeScript, so ja-JP and ar-SA got\n * English word order and no language could change the range separator. The\n * three numbers go through `Intl.NumberFormat` for the same reason the total\n * beside them does — a five-figure total needs the locale's grouping, and\n * ar-SA needs its own digits.\n *\n * The `ofLabel` input is gone with it: an input for the middle word is the\n * concatenation, re-offered as API.\n */\n protected readonly rangeLabel = computed(() => {\n // The same guarded size, or the range label reads \"1 – NaN of 100\".\n const size = this.usablePageSize();\n const start = this.total() === 0 ? 0 : (this.page() - 1) * size + 1;\n const end = Math.min(this.page() * size, this.total());\n return this.rangeText({\n from: this.number(start),\n to: this.number(end),\n total: this.number(this.total()),\n });\n });\n\n /** Internal: the compact pager's `1 / 24`, likewise a catalog template. */\n protected readonly compactLabel = computed(() =>\n this.compactText({ current: this.number(this.page()), total: this.number(this.totalPages()) })\n );\n\n private readonly rangeText = useI18nFormatter('pagination.range', '{{from}}–{{to}} of {{total}}');\n private readonly compactText = useI18nFormatter('pagination.compact', '{{current}} / {{total}}');\n\n private readonly locale = inject(LOCALE_ID);\n\n /**\n * Grouped per `LOCALE_ID`. Only the range and the compact pager go through\n * this — a page NUMBER on a button is an identifier, and `1,024` on a button\n * reads as two things.\n */\n private number(value: number): string {\n return new Intl.NumberFormat(this.locale).format(value);\n }\n\n /**\n * Internal: page list with ellipses. Window of 7 visible page slots.\n *\n * 1 … 5 6 [7] 8 9 … 20\n */\n protected readonly pages = computed<readonly PageEntry[]>(() => {\n const total = this.totalPages();\n const current = this.page();\n\n if (total <= 7) {\n return Array.from({ length: total }, (_, i) => i + 1);\n }\n\n const items: PageEntry[] = [1];\n if (current > 4) items.push(ELLIPSIS);\n\n let start: number;\n let end: number;\n if (current <= 4) {\n start = 2;\n end = 5;\n } else if (current >= total - 3) {\n start = total - 4;\n end = total - 1;\n } else {\n start = current - 2;\n end = current + 2;\n }\n\n for (let i = start; i <= end; i++) items.push(i);\n if (current < total - 3) items.push(ELLIPSIS);\n if (end !== total) items.push(total);\n\n return items;\n });\n\n protected readonly ellipsis = ELLIPSIS;\n\n protected readonly classes = computed(() => {\n const parts = [\n 'wr-pagination',\n `wr-pagination--${this.align()}`,\n `wr-pagination--${this.size()}`,\n `wr-pagination--${this.shape()}`,\n ];\n if (this.disabled()) parts.push('wr-pagination--disabled');\n if (this.responsive()) parts.push('wr-pagination--responsive');\n return parts.join(' ');\n });\n\n protected isCurrent(page: number): boolean {\n return this.page() === page;\n }\n\n protected goTo(page: number | typeof ELLIPSIS): void {\n if (typeof page !== 'number') return;\n if (this.disabled() || page < 1 || page > this.totalPages() || page === this.page()) return;\n this.page.set(page);\n }\n\n /**\n * `wr-select` carries an `unknown` value by design, so the size arrives\n * untyped and is narrowed here. It used to arrive as `any` through\n * `[ngModel]`, which hid the coercion rather than removing the need for it.\n */\n constructor() {\n // `page` is a plain `model` — a `model()` takes no transform — so a\n // shrinking `total` and a host `[(page)]` write both land in it\n // unchecked. The guard used to read and write the page inside `untracked()`\n // and pull DOWNWARDS only, so it fired when `total` / `pageSize` moved and\n // never when the host wrote: past the end no cell carries `aria-current`,\n // the arrow at that end stays enabled and inert (`goTo` refuses the step\n // rather than correcting the stored page), and below 1 `rangeLabel()` counts\n // backwards (\"-9-0 of 120\"). Two-sided and tracked, the same shape\n // `wr-stepper` and `wr-carousel` use for their own host-owned `model()`.\n //\n // Only the UPPER bound is conditional. A `total` at or below 0 is the one\n // value where pulling the page down is destructive rather than cosmetic:\n // there is no `loading` input, so 0 is genuinely ambiguous between \"the\n // list is empty\" and \"the page is still in flight\", and the second is the\n // ordinary state of a server-paged host — Angular's `resource` drops its\n // value whenever the params change, and a params function returning an\n // object literal is never reference-equal, so `total` reads 0 between the\n // click and the response. `totalPages()` is 1 there, so the guard pulled\n // every page above the first back to 1 and emitted a `pageChange`\n // the host could not tell from a click: the pager could not leave page 1,\n // and each click cost two events. A negative `total` is folded into the\n // same branch because it is as meaningless as a zero one.\n //\n // The LOWER bound is unconditional, and gating it on `total` was a mistake\n // in the first cut of this fix: no value of `total` makes page 0 correct,\n // and while it was skipped a host write of -3 survived — `rangeLabel()`\n // guards `start` for an empty total and not `end`, so it read \"0--30 of 0\",\n // and the compact pager read \"-3 / 1\". It is written as one expression\n // rather than an early return so the effect depends on `page()` and\n // `total()` on every run, whichever branch decides the result.\n //\n // What IS still given up while `total` is 0 and the held page is past the\n // first: no cell carries `aria-current`, because `pages` renders the single\n // page and that is not the page the host holds. `rangeLabel()` is not in\n // that list — it already special-cases an empty total and reads \"0-0 of 0\".\n // Nor are the arrows: they compare against the RANGE rather than its ends\n // (see the template), so past the end next renders disabled and prev stays\n // enabled and steps back INTO range via `prevPage`. That is a change from\n // the \"enabled and inert\" behaviour described above, which this component\n // used to accept at both ends.\n effect(() => {\n const page = this.page();\n const floored = Math.max(1, page);\n const clamped = this.total() <= 0 ? floored : Math.min(floored, this.totalPages());\n if (clamped !== page) this.page.set(clamped);\n });\n }\n\n protected onSizeChange(size: unknown): void {\n const next = Number(size);\n if (this.disabled() || !Number.isFinite(next) || next <= 0 || next === this.pageSize()) return;\n // The size and nothing else. This used to clamp the page against the new\n // size too, and it read a value that was already superseded: `pageSize.set`\n // emits `pageSizeChange` synchronously, so by the following statement the\n // host has run its own policy — most tables reset to the first page — and\n // that write has not reached the model yet, it arrives on the next binding\n // pass. So the clamp computed a cap from the PRE-change page and wrote the\n // result over the host's decision: from page 6 at size 10, choosing 25\n // emitted `pageChange(5)` on top of the host's reset to 1, which the\n // host cannot tell from a navigation, and a second request went out. The\n // guard effect in the constructor takes it over and runs once the bindings\n // have settled, so it clamps the page the host actually wants.\n //\n // For a SETTLED `total` that is the whole story. For the server-paged host\n // this fix exists for it is not: the size change invalidates the payload\n // too, so `total` reads 0 and the guard returns early. Measured, from page\n // 6 at size 10 choosing 25 with a host that does not reset — in flight:\n // `navigations []`, page 6, total 0; after settle: `navigations [5]`, page\n // 5. So a non-resetting host issues one doomed request for a page that no\n // longer exists and is corrected only when the answer lands. That is an\n // accepted cost of refusing to write back from transient state, not\n // something the guard covers.\n this.pageSize.set(next);\n }\n}\n","<div class=\"wr-pagination__inner\">\n @if (showTotal()) {\n <span class=\"wr-pagination__total\">{{ rangeLabel() }}</span>\n }\n\n <div class=\"wr-pagination__nav\">\n <!--\n `wr-pagination__nav-btn` exists so the stylesheet can mirror the arrow\n glyph under `dir=\"rtl\"`. A class rather than `:first-child` /\n `:last-child` on the row: those two positions do hold today — which is why\n the `--square` end caps use them — but only while the prev button, the\n compact label and the next button all stay unconditional and in this\n order. A mirror keyed to position would follow a reorder, or land on a\n page cell, without a word.\n\n The two `[disabled]` bindings compare against the RANGE (`<= 1`,\n `>= totalPages()`) rather than for equality with its ends. While `total`\n is 0 the guard effect stops enforcing the upper bound, so the page can\n legitimately sit past `totalPages()` — and `=== totalPages()` reported\n next as enabled there while `goTo` refused the step. Prev is still\n enabled in that state, correctly: `prevPage()` walks it back into range.\n -->\n <wr-btn\n class=\"wr-pagination__nav-btn\"\n [size]=\"size()\"\n outlined\n [attr.aria-label]=\"resolvedPrev()\"\n [disabled]=\"disabled() || page() <= 1\"\n (click)=\"goTo(prevPage())\"\n >\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m12 19-7-7 7-7\" />\n <path d=\"M19 12H5\" />\n </svg>\n </wr-btn>\n\n @for (page of pages(); track $index) {\n @if (page === ellipsis) {\n <span class=\"wr-pagination__ellipsis\">{{ ellipsis }}</span>\n } @else {\n <wr-btn\n class=\"wr-pagination__page\"\n [size]=\"size()\"\n [outlined]=\"!isCurrent(page)\"\n [color]=\"isCurrent(page) ? 'primary' : null\"\n [attr.aria-current]=\"isCurrent(page) ? 'page' : null\"\n [attr.aria-label]=\"goToPage({ page })\"\n [disabled]=\"disabled()\"\n (click)=\"goTo(page)\"\n >\n {{ page }}\n </wr-btn>\n }\n }\n\n <!-- Compact pager — shown only in responsive mode on a narrow box (CSS). -->\n <span class=\"wr-pagination__current\" aria-hidden=\"true\">{{ compactLabel() }}</span>\n\n <wr-btn\n class=\"wr-pagination__nav-btn\"\n [size]=\"size()\"\n outlined\n [attr.aria-label]=\"resolvedNext()\"\n [disabled]=\"disabled() || page() >= totalPages()\"\n (click)=\"goTo(page() + 1)\"\n >\n <svg\n class=\"wr-icon__svg\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M5 12h14\" />\n <path d=\"m12 5 7 7-7 7\" />\n </svg>\n </wr-btn>\n </div>\n\n @if (showSizeChanger()) {\n <!--\n `ariaLabel`, not `[attr.aria-label]`: `<wr-select>`'s host carries no role,\n so an attribute there names nothing and never reaches the `role=\"combobox\"`\n button inside — the size changer announced itself as the catalog's generic\n \"Select\".\n -->\n <wr-select\n class=\"wr-pagination__size\"\n [ariaLabel]=\"resolvedItemsPerPage()\"\n [disabled]=\"disabled()\"\n [value]=\"pageSize()\"\n (valueChange)=\"onSizeChange($event)\"\n >\n @for (option of pageSizeOptions(); track option) {\n <wr-option [value]=\"option\">{{ perPage({ size: option }) }}</wr-option>\n }\n </wr-select>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -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.5", ngImport: i0, type: WrBytes, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
105
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.5", ngImport: i0, type: WrBytes, isStandalone: true, name: "wrBytes" });
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" });
106
106
  }
107
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrBytes, decorators: [{
107
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", 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.5", ngImport: i0, type: WrDate, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
159
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.5", ngImport: i0, type: WrDate, isStandalone: true, name: "wrDate" });
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" });
160
160
  }
161
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrDate, decorators: [{
161
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", 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.5", ngImport: i0, type: WrMark, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
222
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.5", ngImport: i0, type: WrMark, isStandalone: true, name: "wrMark" });
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" });
223
223
  }
224
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrMark, decorators: [{
224
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", 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.5", ngImport: i0, type: WrNumber, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
273
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.5", ngImport: i0, type: WrNumber, isStandalone: true, name: "wrNumber" });
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" });
274
274
  }
275
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrNumber, decorators: [{
275
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", 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.5", ngImport: i0, type: WrPlural, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
319
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.5", ngImport: i0, type: WrPlural, isStandalone: true, name: "wrPlural" });
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" });
320
320
  }
321
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrPlural, decorators: [{
321
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", 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.5", ngImport: i0, type: WrRange, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
349
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.5", ngImport: i0, type: WrRange, isStandalone: true, name: "wrRange" });
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" });
350
350
  }
351
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrRange, decorators: [{
351
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", 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.5", ngImport: i0, type: WrTruncate, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
381
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.5", ngImport: i0, type: WrTruncate, isStandalone: true, name: "wrTruncate" });
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" });
382
382
  }
383
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrTruncate, decorators: [{
383
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrTruncate, decorators: [{
384
384
  type: Pipe,
385
385
  args: [{ name: 'wrTruncate' }]
386
386
  }] });
@@ -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.5", ngImport: i0, type: WrPlatform, deps: [], target: i0.ɵɵFactoryTarget.Service });
52
- static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.5", ngImport: i0, type: WrPlatform });
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 });
53
53
  }
54
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrPlatform, decorators: [{
54
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", 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.5", ngImport: i0, type: WrVisualViewport, deps: [], target: i0.ɵɵFactoryTarget.Service });
114
- static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.5", ngImport: i0, type: WrVisualViewport });
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 });
115
115
  }
116
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrVisualViewport, decorators: [{
116
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", 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.5", ngImport: i0, type: WrHaptics, deps: [], target: i0.ɵɵFactoryTarget.Service });
216
- static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.5", ngImport: i0, type: WrHaptics });
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 });
217
217
  }
218
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.5", ngImport: i0, type: WrHaptics, decorators: [{
218
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrHaptics, decorators: [{
219
219
  type: Service
220
220
  }] });
221
221