ngwr 10.2.0 → 11.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (471) hide show
  1. package/README.md +39 -19
  2. package/anchor/styles/_index.scss +4 -4
  3. package/back-top/styles/_index.scss +6 -1
  4. package/blur-text/styles/_index.scss +13 -0
  5. package/button/styles/_index.scss +11 -6
  6. package/carousel/styles/_index.scss +13 -2
  7. package/cascader/styles/_index.scss +2 -2
  8. package/circular-text/styles/_index.scss +2 -0
  9. package/collapse/styles/_index.scss +1 -1
  10. package/color-picker/styles/_index.scss +6 -1
  11. package/compare/styles/_index.scss +1 -2
  12. package/context-menu/styles/_index.scss +6 -1
  13. package/descriptions/styles/_index.scss +2 -2
  14. package/dialog/styles/_index.scss +38 -0
  15. package/drawer/styles/_index.scss +20 -1
  16. package/dropdown/styles/_index.scss +19 -5
  17. package/empty/styles/_index.scss +10 -0
  18. package/fesm2022/ngwr-action-sheet.mjs +15 -5
  19. package/fesm2022/ngwr-action-sheet.mjs.map +1 -1
  20. package/fesm2022/ngwr-affix.mjs +43 -16
  21. package/fesm2022/ngwr-affix.mjs.map +1 -1
  22. package/fesm2022/ngwr-alert.mjs +3 -3
  23. package/fesm2022/ngwr-anchor.mjs +20 -8
  24. package/fesm2022/ngwr-anchor.mjs.map +1 -1
  25. package/fesm2022/ngwr-aurora.mjs +4 -4
  26. package/fesm2022/ngwr-aurora.mjs.map +1 -1
  27. package/fesm2022/ngwr-avatar.mjs +33 -9
  28. package/fesm2022/ngwr-avatar.mjs.map +1 -1
  29. package/fesm2022/ngwr-back-top.mjs +8 -4
  30. package/fesm2022/ngwr-back-top.mjs.map +1 -1
  31. package/fesm2022/ngwr-badge.mjs +6 -6
  32. package/fesm2022/ngwr-badge.mjs.map +1 -1
  33. package/fesm2022/ngwr-bar-chart.mjs +32 -11
  34. package/fesm2022/ngwr-bar-chart.mjs.map +1 -1
  35. package/fesm2022/ngwr-blur-text.mjs +4 -4
  36. package/fesm2022/ngwr-blur-text.mjs.map +1 -1
  37. package/fesm2022/ngwr-border-glow.mjs +4 -4
  38. package/fesm2022/ngwr-border-glow.mjs.map +1 -1
  39. package/fesm2022/ngwr-breadcrumbs.mjs +9 -8
  40. package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
  41. package/fesm2022/ngwr-burger.mjs +11 -6
  42. package/fesm2022/ngwr-burger.mjs.map +1 -1
  43. package/fesm2022/ngwr-button-testing.mjs +96 -0
  44. package/fesm2022/ngwr-button-testing.mjs.map +1 -0
  45. package/fesm2022/ngwr-button.mjs +89 -24
  46. package/fesm2022/ngwr-button.mjs.map +1 -1
  47. package/fesm2022/ngwr-calendar-heatmap.mjs +42 -10
  48. package/fesm2022/ngwr-calendar-heatmap.mjs.map +1 -1
  49. package/fesm2022/ngwr-calendar.mjs +108 -9
  50. package/fesm2022/ngwr-calendar.mjs.map +1 -1
  51. package/fesm2022/ngwr-card.mjs +10 -10
  52. package/fesm2022/ngwr-card.mjs.map +1 -1
  53. package/fesm2022/ngwr-carousel-testing.mjs +377 -0
  54. package/fesm2022/ngwr-carousel-testing.mjs.map +1 -0
  55. package/fesm2022/ngwr-carousel.mjs +72 -18
  56. package/fesm2022/ngwr-carousel.mjs.map +1 -1
  57. package/fesm2022/ngwr-cascader-testing.mjs +534 -0
  58. package/fesm2022/ngwr-cascader-testing.mjs.map +1 -0
  59. package/fesm2022/ngwr-cascader.mjs +4 -4
  60. package/fesm2022/ngwr-cascader.mjs.map +1 -1
  61. package/fesm2022/ngwr-checkbox-testing.mjs +90 -0
  62. package/fesm2022/ngwr-checkbox-testing.mjs.map +1 -0
  63. package/fesm2022/ngwr-checkbox.mjs +15 -9
  64. package/fesm2022/ngwr-checkbox.mjs.map +1 -1
  65. package/fesm2022/ngwr-circular-text.mjs +4 -4
  66. package/fesm2022/ngwr-circular-text.mjs.map +1 -1
  67. package/fesm2022/ngwr-click-spark.mjs +4 -4
  68. package/fesm2022/ngwr-click-spark.mjs.map +1 -1
  69. package/fesm2022/ngwr-clipboard.mjs +18 -4
  70. package/fesm2022/ngwr-clipboard.mjs.map +1 -1
  71. package/fesm2022/ngwr-collapse-testing.mjs +368 -0
  72. package/fesm2022/ngwr-collapse-testing.mjs.map +1 -0
  73. package/fesm2022/ngwr-collapse.mjs +9 -9
  74. package/fesm2022/ngwr-color-picker.mjs +139 -19
  75. package/fesm2022/ngwr-color-picker.mjs.map +1 -1
  76. package/fesm2022/ngwr-command-palette-testing.mjs +589 -0
  77. package/fesm2022/ngwr-command-palette-testing.mjs.map +1 -0
  78. package/fesm2022/ngwr-command-palette.mjs +60 -10
  79. package/fesm2022/ngwr-command-palette.mjs.map +1 -1
  80. package/fesm2022/ngwr-compare.mjs +105 -15
  81. package/fesm2022/ngwr-compare.mjs.map +1 -1
  82. package/fesm2022/ngwr-confetti.mjs +3 -3
  83. package/fesm2022/ngwr-config.mjs +106 -0
  84. package/fesm2022/ngwr-config.mjs.map +1 -0
  85. package/fesm2022/ngwr-context-menu-testing.mjs +631 -0
  86. package/fesm2022/ngwr-context-menu-testing.mjs.map +1 -0
  87. package/fesm2022/ngwr-context-menu.mjs +104 -18
  88. package/fesm2022/ngwr-context-menu.mjs.map +1 -1
  89. package/fesm2022/ngwr-cookie.mjs +8 -4
  90. package/fesm2022/ngwr-cookie.mjs.map +1 -1
  91. package/fesm2022/ngwr-counter.mjs +17 -9
  92. package/fesm2022/ngwr-counter.mjs.map +1 -1
  93. package/fesm2022/ngwr-date-adapter-fns.mjs +3 -3
  94. package/fesm2022/ngwr-date-adapter-luxon.mjs +55 -7
  95. package/fesm2022/ngwr-date-adapter-luxon.mjs.map +1 -1
  96. package/fesm2022/ngwr-date-adapter.mjs +57 -11
  97. package/fesm2022/ngwr-date-adapter.mjs.map +1 -1
  98. package/fesm2022/ngwr-date-picker-testing.mjs +766 -0
  99. package/fesm2022/ngwr-date-picker-testing.mjs.map +1 -0
  100. package/fesm2022/ngwr-date-picker.mjs +409 -57
  101. package/fesm2022/ngwr-date-picker.mjs.map +1 -1
  102. package/fesm2022/ngwr-decrypt-text.mjs +30 -12
  103. package/fesm2022/ngwr-decrypt-text.mjs.map +1 -1
  104. package/fesm2022/ngwr-density.mjs +6 -6
  105. package/fesm2022/ngwr-descriptions.mjs +6 -6
  106. package/fesm2022/ngwr-dialog-testing.mjs +89 -0
  107. package/fesm2022/ngwr-dialog-testing.mjs.map +1 -0
  108. package/fesm2022/ngwr-dialog.mjs +33 -17
  109. package/fesm2022/ngwr-dialog.mjs.map +1 -1
  110. package/fesm2022/ngwr-directives.mjs +48 -24
  111. package/fesm2022/ngwr-directives.mjs.map +1 -1
  112. package/fesm2022/ngwr-divider.mjs +3 -3
  113. package/fesm2022/ngwr-donut-chart.mjs +24 -7
  114. package/fesm2022/ngwr-donut-chart.mjs.map +1 -1
  115. package/fesm2022/ngwr-drag-drop.mjs +7 -7
  116. package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
  117. package/fesm2022/ngwr-drawer-testing.mjs +250 -0
  118. package/fesm2022/ngwr-drawer-testing.mjs.map +1 -0
  119. package/fesm2022/ngwr-drawer.mjs +37 -19
  120. package/fesm2022/ngwr-drawer.mjs.map +1 -1
  121. package/fesm2022/ngwr-dropdown-testing.mjs +291 -0
  122. package/fesm2022/ngwr-dropdown-testing.mjs.map +1 -0
  123. package/fesm2022/ngwr-dropdown.mjs +19 -11
  124. package/fesm2022/ngwr-dropdown.mjs.map +1 -1
  125. package/fesm2022/ngwr-empty.mjs +26 -9
  126. package/fesm2022/ngwr-empty.mjs.map +1 -1
  127. package/fesm2022/ngwr-event-calendar.mjs +62 -15
  128. package/fesm2022/ngwr-event-calendar.mjs.map +1 -1
  129. package/fesm2022/ngwr-falling-text.mjs +4 -4
  130. package/fesm2022/ngwr-falling-text.mjs.map +1 -1
  131. package/fesm2022/ngwr-file-upload-testing.mjs +332 -0
  132. package/fesm2022/ngwr-file-upload-testing.mjs.map +1 -0
  133. package/fesm2022/ngwr-file-upload.mjs +3 -3
  134. package/fesm2022/ngwr-form-testing.mjs +451 -0
  135. package/fesm2022/ngwr-form-testing.mjs.map +1 -0
  136. package/fesm2022/ngwr-form.mjs +28 -12
  137. package/fesm2022/ngwr-form.mjs.map +1 -1
  138. package/fesm2022/ngwr-fuzzy-text.mjs +11 -4
  139. package/fesm2022/ngwr-fuzzy-text.mjs.map +1 -1
  140. package/fesm2022/ngwr-gauge.mjs +21 -7
  141. package/fesm2022/ngwr-gauge.mjs.map +1 -1
  142. package/fesm2022/ngwr-glitch-text.mjs +4 -4
  143. package/fesm2022/ngwr-glitch-text.mjs.map +1 -1
  144. package/fesm2022/ngwr-gradient-text.mjs +4 -4
  145. package/fesm2022/ngwr-gradient-text.mjs.map +1 -1
  146. package/fesm2022/ngwr-hotkey.mjs +31 -10
  147. package/fesm2022/ngwr-hotkey.mjs.map +1 -1
  148. package/fesm2022/ngwr-i18n-en.mjs +61 -0
  149. package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
  150. package/fesm2022/ngwr-i18n-ru.mjs +59 -0
  151. package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
  152. package/fesm2022/ngwr-i18n.mjs +9 -9
  153. package/fesm2022/ngwr-icon.mjs +6 -6
  154. package/fesm2022/ngwr-image-cropper.mjs +26 -3
  155. package/fesm2022/ngwr-image-cropper.mjs.map +1 -1
  156. package/fesm2022/ngwr-input-number-testing.mjs +306 -0
  157. package/fesm2022/ngwr-input-number-testing.mjs.map +1 -0
  158. package/fesm2022/ngwr-input-number.mjs +37 -5
  159. package/fesm2022/ngwr-input-number.mjs.map +1 -1
  160. package/fesm2022/ngwr-input-otp-testing.mjs +419 -0
  161. package/fesm2022/ngwr-input-otp-testing.mjs.map +1 -0
  162. package/fesm2022/ngwr-input-otp.mjs +39 -8
  163. package/fesm2022/ngwr-input-otp.mjs.map +1 -1
  164. package/fesm2022/ngwr-input-testing.mjs +102 -0
  165. package/fesm2022/ngwr-input-testing.mjs.map +1 -0
  166. package/fesm2022/ngwr-input.mjs +62 -25
  167. package/fesm2022/ngwr-input.mjs.map +1 -1
  168. package/fesm2022/ngwr-keyboard.mjs +3 -3
  169. package/fesm2022/ngwr-knob.mjs +46 -10
  170. package/fesm2022/ngwr-knob.mjs.map +1 -1
  171. package/fesm2022/ngwr-layout.mjs +36 -20
  172. package/fesm2022/ngwr-layout.mjs.map +1 -1
  173. package/fesm2022/ngwr-lightbox.mjs +35 -8
  174. package/fesm2022/ngwr-lightbox.mjs.map +1 -1
  175. package/fesm2022/ngwr-line-chart.mjs +19 -6
  176. package/fesm2022/ngwr-line-chart.mjs.map +1 -1
  177. package/fesm2022/ngwr-list.mjs +14 -9
  178. package/fesm2022/ngwr-list.mjs.map +1 -1
  179. package/fesm2022/ngwr-loading-bar.mjs +71 -31
  180. package/fesm2022/ngwr-loading-bar.mjs.map +1 -1
  181. package/fesm2022/ngwr-markdown-testing.mjs +516 -0
  182. package/fesm2022/ngwr-markdown-testing.mjs.map +1 -0
  183. package/fesm2022/ngwr-markdown.mjs +1492 -0
  184. package/fesm2022/ngwr-markdown.mjs.map +1 -0
  185. package/fesm2022/ngwr-marquee.mjs +19 -8
  186. package/fesm2022/ngwr-marquee.mjs.map +1 -1
  187. package/fesm2022/ngwr-media.mjs +3 -3
  188. package/fesm2022/ngwr-mention-testing.mjs +513 -0
  189. package/fesm2022/ngwr-mention-testing.mjs.map +1 -0
  190. package/fesm2022/ngwr-mention.mjs +16 -7
  191. package/fesm2022/ngwr-mention.mjs.map +1 -1
  192. package/fesm2022/ngwr-meta.mjs +28 -13
  193. package/fesm2022/ngwr-meta.mjs.map +1 -1
  194. package/fesm2022/ngwr-meter-group.mjs +22 -8
  195. package/fesm2022/ngwr-meter-group.mjs.map +1 -1
  196. package/fesm2022/ngwr-overlay.mjs +57 -8
  197. package/fesm2022/ngwr-overlay.mjs.map +1 -1
  198. package/fesm2022/ngwr-page-header.mjs +3 -3
  199. package/fesm2022/ngwr-pagination-testing.mjs +389 -0
  200. package/fesm2022/ngwr-pagination-testing.mjs.map +1 -0
  201. package/fesm2022/ngwr-pagination.mjs +27 -11
  202. package/fesm2022/ngwr-pagination.mjs.map +1 -1
  203. package/fesm2022/ngwr-pipes.mjs +21 -21
  204. package/fesm2022/ngwr-platform.mjs +9 -9
  205. package/fesm2022/ngwr-popconfirm-testing.mjs +309 -0
  206. package/fesm2022/ngwr-popconfirm-testing.mjs.map +1 -0
  207. package/fesm2022/ngwr-popconfirm.mjs +99 -21
  208. package/fesm2022/ngwr-popconfirm.mjs.map +1 -1
  209. package/fesm2022/ngwr-popover-testing.mjs +316 -0
  210. package/fesm2022/ngwr-popover-testing.mjs.map +1 -0
  211. package/fesm2022/ngwr-popover.mjs +48 -10
  212. package/fesm2022/ngwr-popover.mjs.map +1 -1
  213. package/fesm2022/ngwr-progress.mjs +3 -3
  214. package/fesm2022/ngwr-pull-to-refresh.mjs +19 -4
  215. package/fesm2022/ngwr-pull-to-refresh.mjs.map +1 -1
  216. package/fesm2022/ngwr-qr.mjs +15 -5
  217. package/fesm2022/ngwr-qr.mjs.map +1 -1
  218. package/fesm2022/ngwr-radio-testing.mjs +392 -0
  219. package/fesm2022/ngwr-radio-testing.mjs.map +1 -0
  220. package/fesm2022/ngwr-radio.mjs +16 -9
  221. package/fesm2022/ngwr-radio.mjs.map +1 -1
  222. package/fesm2022/ngwr-rating-testing.mjs +384 -0
  223. package/fesm2022/ngwr-rating-testing.mjs.map +1 -0
  224. package/fesm2022/ngwr-rating.mjs +40 -5
  225. package/fesm2022/ngwr-rating.mjs.map +1 -1
  226. package/fesm2022/ngwr-result.mjs +12 -12
  227. package/fesm2022/ngwr-rotating-text.mjs +3 -3
  228. package/fesm2022/ngwr-scroll.mjs +3 -3
  229. package/fesm2022/ngwr-segmented-testing.mjs +512 -0
  230. package/fesm2022/ngwr-segmented-testing.mjs.map +1 -0
  231. package/fesm2022/ngwr-segmented.mjs +3 -3
  232. package/fesm2022/ngwr-select-testing.mjs +268 -0
  233. package/fesm2022/ngwr-select-testing.mjs.map +1 -0
  234. package/fesm2022/ngwr-select.mjs +96 -25
  235. package/fesm2022/ngwr-select.mjs.map +1 -1
  236. package/fesm2022/ngwr-shiny-text.mjs +7 -7
  237. package/fesm2022/ngwr-shiny-text.mjs.map +1 -1
  238. package/fesm2022/ngwr-sidebar.mjs +67 -14
  239. package/fesm2022/ngwr-sidebar.mjs.map +1 -1
  240. package/fesm2022/ngwr-skeleton.mjs +3 -3
  241. package/fesm2022/ngwr-slider-testing.mjs +478 -0
  242. package/fesm2022/ngwr-slider-testing.mjs.map +1 -0
  243. package/fesm2022/ngwr-slider.mjs +59 -15
  244. package/fesm2022/ngwr-slider.mjs.map +1 -1
  245. package/fesm2022/ngwr-sparkline.mjs +28 -8
  246. package/fesm2022/ngwr-sparkline.mjs.map +1 -1
  247. package/fesm2022/ngwr-speed-dial.mjs +39 -6
  248. package/fesm2022/ngwr-speed-dial.mjs.map +1 -1
  249. package/fesm2022/ngwr-spinner.mjs +14 -5
  250. package/fesm2022/ngwr-spinner.mjs.map +1 -1
  251. package/fesm2022/ngwr-splash-cursor.mjs +4 -4
  252. package/fesm2022/ngwr-splash-cursor.mjs.map +1 -1
  253. package/fesm2022/ngwr-split-text.mjs +4 -4
  254. package/fesm2022/ngwr-split-text.mjs.map +1 -1
  255. package/fesm2022/ngwr-splitter.mjs +72 -11
  256. package/fesm2022/ngwr-splitter.mjs.map +1 -1
  257. package/fesm2022/ngwr-spotlight-card.mjs +7 -7
  258. package/fesm2022/ngwr-spotlight-card.mjs.map +1 -1
  259. package/fesm2022/ngwr-squircle.mjs +6 -6
  260. package/fesm2022/ngwr-star-border.mjs +4 -4
  261. package/fesm2022/ngwr-star-border.mjs.map +1 -1
  262. package/fesm2022/ngwr-statistic.mjs +33 -16
  263. package/fesm2022/ngwr-statistic.mjs.map +1 -1
  264. package/fesm2022/ngwr-stepper-testing.mjs +477 -0
  265. package/fesm2022/ngwr-stepper-testing.mjs.map +1 -0
  266. package/fesm2022/ngwr-stepper.mjs +6 -6
  267. package/fesm2022/ngwr-storage.mjs +27 -17
  268. package/fesm2022/ngwr-storage.mjs.map +1 -1
  269. package/fesm2022/ngwr-switch-testing.mjs +77 -0
  270. package/fesm2022/ngwr-switch-testing.mjs.map +1 -0
  271. package/fesm2022/ngwr-switch.mjs +12 -6
  272. package/fesm2022/ngwr-switch.mjs.map +1 -1
  273. package/fesm2022/ngwr-table-testing.mjs +580 -0
  274. package/fesm2022/ngwr-table-testing.mjs.map +1 -0
  275. package/fesm2022/ngwr-table.mjs +105 -44
  276. package/fesm2022/ngwr-table.mjs.map +1 -1
  277. package/fesm2022/ngwr-tabs-testing.mjs +617 -0
  278. package/fesm2022/ngwr-tabs-testing.mjs.map +1 -0
  279. package/fesm2022/ngwr-tabs.mjs +44 -12
  280. package/fesm2022/ngwr-tabs.mjs.map +1 -1
  281. package/fesm2022/ngwr-textarea-testing.mjs +238 -0
  282. package/fesm2022/ngwr-textarea-testing.mjs.map +1 -0
  283. package/fesm2022/ngwr-textarea.mjs +35 -7
  284. package/fesm2022/ngwr-textarea.mjs.map +1 -1
  285. package/fesm2022/ngwr-theme.mjs +3 -3
  286. package/fesm2022/ngwr-tilt-card.mjs +7 -7
  287. package/fesm2022/ngwr-tilt-card.mjs.map +1 -1
  288. package/fesm2022/ngwr-timeline.mjs +6 -6
  289. package/fesm2022/ngwr-toast-testing.mjs +101 -0
  290. package/fesm2022/ngwr-toast-testing.mjs.map +1 -0
  291. package/fesm2022/ngwr-toast.mjs +55 -21
  292. package/fesm2022/ngwr-toast.mjs.map +1 -1
  293. package/fesm2022/ngwr-toolbar.mjs +3 -3
  294. package/fesm2022/ngwr-tour.mjs +67 -15
  295. package/fesm2022/ngwr-tour.mjs.map +1 -1
  296. package/fesm2022/ngwr-transfer-testing.mjs +538 -0
  297. package/fesm2022/ngwr-transfer-testing.mjs.map +1 -0
  298. package/fesm2022/ngwr-transfer.mjs +47 -16
  299. package/fesm2022/ngwr-transfer.mjs.map +1 -1
  300. package/fesm2022/ngwr-tree-testing.mjs +734 -0
  301. package/fesm2022/ngwr-tree-testing.mjs.map +1 -0
  302. package/fesm2022/ngwr-tree.mjs +75 -9
  303. package/fesm2022/ngwr-tree.mjs.map +1 -1
  304. package/fesm2022/ngwr-typewriter.mjs +7 -5
  305. package/fesm2022/ngwr-typewriter.mjs.map +1 -1
  306. package/fesm2022/ngwr-typography.mjs +3 -3
  307. package/fesm2022/ngwr-version.mjs +1 -1
  308. package/fesm2022/ngwr-version.mjs.map +1 -1
  309. package/fesm2022/ngwr-virtual-scroll.mjs +33 -7
  310. package/fesm2022/ngwr-virtual-scroll.mjs.map +1 -1
  311. package/fesm2022/ngwr-waves.mjs +5 -5
  312. package/fesm2022/ngwr-waves.mjs.map +1 -1
  313. package/fesm2022/ngwr-window.mjs +88 -18
  314. package/fesm2022/ngwr-window.mjs.map +1 -1
  315. package/gauge/styles/_index.scss +1 -1
  316. package/glitch-text/styles/_index.scss +4 -0
  317. package/i18n/en.json +56 -0
  318. package/i18n/ru.json +56 -0
  319. package/image-cropper/styles/_index.scss +13 -1
  320. package/input/styles/_index.scss +2 -2
  321. package/input-number/styles/_index.scss +7 -2
  322. package/knob/styles/_index.scss +8 -1
  323. package/layout/styles/_index.scss +3 -3
  324. package/lightbox/styles/_index.scss +10 -2
  325. package/line-chart/styles/_index.scss +6 -0
  326. package/llms-full.txt +151 -4
  327. package/llms.txt +57 -8
  328. package/loading-bar/styles/_index.scss +1 -2
  329. package/markdown/styles/_index.scss +296 -0
  330. package/marquee/styles/_index.scss +12 -0
  331. package/mcp/api.js +512 -0
  332. package/mcp/catalog.js +157 -0
  333. package/mcp/server.js +273 -0
  334. package/mcp/tools.js +366 -0
  335. package/meter-group/styles/_index.scss +1 -1
  336. package/package.json +186 -35
  337. package/pagination/styles/_index.scss +6 -6
  338. package/popover/styles/_index.scss +37 -5
  339. package/rating/styles/_index.scss +10 -0
  340. package/schematics/use/symbol-map.json +2 -0
  341. package/segmented/styles/_index.scss +7 -0
  342. package/select/styles/_index.scss +29 -9
  343. package/sidebar/styles/_index.scss +30 -5
  344. package/slider/styles/_index.scss +15 -0
  345. package/speed-dial/styles/_index.scss +20 -0
  346. package/split-text/styles/_index.scss +13 -0
  347. package/star-border/styles/_index.scss +2 -0
  348. package/stepper/styles/_index.scss +1 -1
  349. package/styles/_grid.scss +4 -4
  350. package/styles.scss +1 -0
  351. package/switch/styles/_index.scss +5 -3
  352. package/table/styles/_index.scss +22 -11
  353. package/tabs/styles/_index.scss +11 -1
  354. package/textarea/styles/_index.scss +5 -0
  355. package/theme/styles/_colors.scss +29 -13
  356. package/theme/styles/_dark.scss +11 -3
  357. package/theme/styles/_mixins.scss +3 -0
  358. package/timeline/styles/_index.scss +2 -2
  359. package/toast/styles/_index.scss +17 -8
  360. package/toolbar/styles/_index.scss +3 -3
  361. package/tour/styles/_index.scss +7 -1
  362. package/tree/styles/_index.scss +5 -3
  363. package/types/ngwr-action-sheet.d.ts +9 -1
  364. package/types/ngwr-affix.d.ts +7 -1
  365. package/types/ngwr-anchor.d.ts +8 -1
  366. package/types/ngwr-avatar.d.ts +13 -3
  367. package/types/ngwr-bar-chart.d.ts +16 -0
  368. package/types/ngwr-burger.d.ts +6 -2
  369. package/types/ngwr-button-testing.d.ts +85 -0
  370. package/types/ngwr-button.d.ts +58 -10
  371. package/types/ngwr-calendar-heatmap.d.ts +16 -2
  372. package/types/ngwr-calendar.d.ts +37 -1
  373. package/types/ngwr-carousel-testing.d.ts +257 -0
  374. package/types/ngwr-carousel.d.ts +20 -4
  375. package/types/ngwr-cascader-testing.d.ts +392 -0
  376. package/types/ngwr-checkbox-testing.d.ts +77 -0
  377. package/types/ngwr-checkbox.d.ts +7 -2
  378. package/types/ngwr-clipboard.d.ts +8 -1
  379. package/types/ngwr-collapse-testing.d.ts +290 -0
  380. package/types/ngwr-color-picker.d.ts +20 -11
  381. package/types/ngwr-command-palette-testing.d.ts +437 -0
  382. package/types/ngwr-command-palette.d.ts +25 -2
  383. package/types/ngwr-compare.d.ts +50 -2
  384. package/types/ngwr-config.d.ts +176 -0
  385. package/types/ngwr-context-menu-testing.d.ts +401 -0
  386. package/types/ngwr-context-menu.d.ts +65 -17
  387. package/types/ngwr-counter.d.ts +6 -1
  388. package/types/ngwr-date-adapter-luxon.d.ts +26 -0
  389. package/types/ngwr-date-picker-testing.d.ts +518 -0
  390. package/types/ngwr-date-picker.d.ts +128 -8
  391. package/types/ngwr-dialog-testing.d.ts +79 -0
  392. package/types/ngwr-dialog.d.ts +13 -0
  393. package/types/ngwr-directives.d.ts +10 -1
  394. package/types/ngwr-donut-chart.d.ts +8 -1
  395. package/types/ngwr-drawer-testing.d.ts +196 -0
  396. package/types/ngwr-drawer.d.ts +15 -0
  397. package/types/ngwr-dropdown-testing.d.ts +202 -0
  398. package/types/ngwr-dropdown.d.ts +7 -1
  399. package/types/ngwr-empty.d.ts +19 -4
  400. package/types/ngwr-event-calendar.d.ts +26 -1
  401. package/types/ngwr-file-upload-testing.d.ts +194 -0
  402. package/types/ngwr-form-testing.d.ts +379 -0
  403. package/types/ngwr-form.d.ts +17 -0
  404. package/types/ngwr-gauge.d.ts +13 -1
  405. package/types/ngwr-hotkey.d.ts +2 -0
  406. package/types/ngwr-image-cropper.d.ts +10 -0
  407. package/types/ngwr-input-number-testing.d.ts +226 -0
  408. package/types/ngwr-input-number.d.ts +29 -1
  409. package/types/ngwr-input-otp-testing.d.ts +299 -0
  410. package/types/ngwr-input-otp.d.ts +23 -2
  411. package/types/ngwr-input-testing.d.ts +84 -0
  412. package/types/ngwr-input.d.ts +20 -6
  413. package/types/ngwr-knob.d.ts +18 -0
  414. package/types/ngwr-layout.d.ts +1 -0
  415. package/types/ngwr-lightbox.d.ts +17 -3
  416. package/types/ngwr-line-chart.d.ts +9 -2
  417. package/types/ngwr-list.d.ts +7 -2
  418. package/types/ngwr-loading-bar.d.ts +4 -7
  419. package/types/ngwr-markdown-testing.d.ts +462 -0
  420. package/types/ngwr-markdown.d.ts +534 -0
  421. package/types/ngwr-marquee.d.ts +12 -2
  422. package/types/ngwr-mention-testing.d.ts +359 -0
  423. package/types/ngwr-meta.d.ts +4 -2
  424. package/types/ngwr-meter-group.d.ts +11 -1
  425. package/types/ngwr-overlay.d.ts +33 -2
  426. package/types/ngwr-pagination-testing.d.ts +291 -0
  427. package/types/ngwr-pagination.d.ts +7 -1
  428. package/types/ngwr-popconfirm-testing.d.ts +235 -0
  429. package/types/ngwr-popconfirm.d.ts +31 -21
  430. package/types/ngwr-popover-testing.d.ts +221 -0
  431. package/types/ngwr-popover.d.ts +19 -2
  432. package/types/ngwr-pull-to-refresh.d.ts +7 -0
  433. package/types/ngwr-qr.d.ts +9 -1
  434. package/types/ngwr-radio-testing.d.ts +296 -0
  435. package/types/ngwr-radio.d.ts +8 -2
  436. package/types/ngwr-rating-testing.d.ts +291 -0
  437. package/types/ngwr-rating.d.ts +23 -0
  438. package/types/ngwr-segmented-testing.d.ts +401 -0
  439. package/types/ngwr-select-testing.d.ts +175 -0
  440. package/types/ngwr-select.d.ts +45 -4
  441. package/types/ngwr-sidebar.d.ts +17 -2
  442. package/types/ngwr-slider-testing.d.ts +329 -0
  443. package/types/ngwr-slider.d.ts +35 -1
  444. package/types/ngwr-sparkline.d.ts +12 -2
  445. package/types/ngwr-speed-dial.d.ts +17 -18
  446. package/types/ngwr-spinner.d.ts +8 -1
  447. package/types/ngwr-splitter.d.ts +24 -1
  448. package/types/ngwr-statistic.d.ts +12 -2
  449. package/types/ngwr-stepper-testing.d.ts +346 -0
  450. package/types/ngwr-storage.d.ts +10 -1
  451. package/types/ngwr-switch-testing.d.ts +66 -0
  452. package/types/ngwr-switch.d.ts +7 -2
  453. package/types/ngwr-table-testing.d.ts +423 -0
  454. package/types/ngwr-table.d.ts +42 -0
  455. package/types/ngwr-tabs-testing.d.ts +470 -0
  456. package/types/ngwr-tabs.d.ts +9 -0
  457. package/types/ngwr-textarea-testing.d.ts +184 -0
  458. package/types/ngwr-textarea.d.ts +7 -2
  459. package/types/ngwr-toast-testing.d.ts +80 -0
  460. package/types/ngwr-toast.d.ts +19 -4
  461. package/types/ngwr-tour.d.ts +27 -0
  462. package/types/ngwr-transfer-testing.d.ts +444 -0
  463. package/types/ngwr-transfer.d.ts +16 -1
  464. package/types/ngwr-tree-testing.d.ts +501 -0
  465. package/types/ngwr-tree.d.ts +33 -0
  466. package/types/ngwr-version.d.ts +1 -1
  467. package/types/ngwr-virtual-scroll.d.ts +13 -1
  468. package/types/ngwr-window.d.ts +23 -2
  469. package/typewriter/styles/_index.scss +1 -1
  470. package/typography/styles/_index.scss +1 -1
  471. package/window/styles/_index.scss +32 -9
@@ -0,0 +1,389 @@
1
+ import { ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';
2
+ import { WrButtonHarness } from 'ngwr/button/testing';
3
+ import { WrSelectHarness } from 'ngwr/select/testing';
4
+
5
+ /**
6
+ * @license
7
+ *
8
+ * Use of this source code is governed by an MIT-style license that can be
9
+ * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
10
+ */
11
+ /**
12
+ * Test harness for `<wr-pagination>` — the numbered strip, its two step controls,
13
+ * the total label and the page-size changer.
14
+ *
15
+ * The strip is not the page list: it is a WINDOW over it, at most seven pages wide,
16
+ * with an `…` standing in for every page it skipped. So "which pages can I click"
17
+ * and "how many pages are there" are different questions and this harness keeps
18
+ * them apart —
19
+ * {@link getPages} answers the first, {@link getTotalPages} the second, and
20
+ * {@link getStrip} shows the gaps for what they are. A gap is a `<span>`, not a
21
+ * control; counting the strip's children as pages is the mistake this API exists to
22
+ * make impossible.
23
+ *
24
+ * **Which page is current has two answers, and this reads the ARIA one.** The
25
+ * current cell is also PAINTED — the template binds
26
+ * `[color]="isCurrent(page) ? 'primary' : null"`, so `.wr-btn--primary` sits on it
27
+ * too. But colour is a theming decision (`ngwr/config` names this very binding as
28
+ * the reason it ships no app-wide `color` default), while `aria-current="page"` is
29
+ * the navigation contract: it is what a screen-reader user hears, what the
30
+ * component's own spec pins, and the only one of the two that still means
31
+ * "you are here" after a restyle. A harness that read the class would be reporting
32
+ * on the paint.
33
+ *
34
+ * **No roving tab stop to disambiguate.** Every cell is a `<wr-btn>` ELEMENT with
35
+ * its own tab stop (`tabindex="0"`, dropped only while the control is off), so the
36
+ * pager has no separate "focused" item that could drift from the current page —
37
+ * unlike a tab strip or a radio group, there is one active state here and
38
+ * {@link getCurrentPage} is it.
39
+ *
40
+ * Composed rather than re-queried: the cells and step controls are driven through
41
+ * {@link WrButtonHarness}, which already knows how a `<wr-btn>` says it is off —
42
+ * both the `disabled` attribute (written on every shape, though inert on a custom
43
+ * element) and `aria-disabled`, in that order — and the size changer through
44
+ * {@link WrSelectHarness}, whose panel is a portal in the overlay container and
45
+ * nowhere inside the pager.
46
+ *
47
+ * jsdom notes: every method here is a class / attribute read or a no-arg click, so
48
+ * none of it needs layout. Two things are therefore invisible in a unit test and
49
+ * deliberately absent from this API — the responsive collapse, which is a container
50
+ * query ({@link isResponsive} reports only that it is ALLOWED), and the compact
51
+ * `‹ 3 / 10 ›` pager it swaps in, which is `aria-hidden` decoration duplicating
52
+ * {@link getCurrentPage} and {@link getTotalPages} and which a real browser would
53
+ * read as empty text while CSS keeps it hidden.
54
+ *
55
+ * @example
56
+ * ```ts
57
+ * const pager = await loader.getHarness(WrPaginationHarness);
58
+ *
59
+ * expect(await pager.getPages()).toEqual([1, 2, 3, 4, 5, 10]);
60
+ * await pager.goToPage(3);
61
+ * expect(await pager.getCurrentPage()).toBe(3);
62
+ * ```
63
+ *
64
+ * @see https://ngwr.dev/guides/testing
65
+ */
66
+ class WrPaginationHarness extends ComponentHarness {
67
+ static hostSelector = 'wr-pagination';
68
+ /** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */
69
+ static with(options = {}) {
70
+ return new HarnessPredicate(WrPaginationHarness, options)
71
+ .addOption('label', options.label, (harness, label) => HarnessPredicate.stringMatches(harness.getLabel(), label))
72
+ .addOption('currentPage', options.currentPage, async (harness, page) => {
73
+ // The nullable read on purpose: the throwing getter would reject the whole
74
+ // query over one pager that announces no current page, taking its
75
+ // well-behaved neighbours down with it.
76
+ return (await harness.currentPageOrNull()) === page;
77
+ })
78
+ .addOption('disabled', options.disabled, async (harness, disabled) => (await harness.isDisabled()) === disabled);
79
+ }
80
+ /** The numbered cells, in DOM order — ascending, and never a gap. */
81
+ pageCells = this.locatorForAll(WrButtonHarness.with({ selector: '.wr-pagination__page' }));
82
+ /**
83
+ * The two controls bracketing the strip: previous, then next.
84
+ *
85
+ * Located by POSITION, not by their labels. `prevLabel` / `nextLabel` are inputs
86
+ * and both fall back to the `pagination.prev` / `pagination.next` catalog entries,
87
+ * so an English `aria-label` match works right up until someone ships a locale —
88
+ * whereas the nav's shape (one step control, the strip, one step control) is
89
+ * structural. `:not(.wr-pagination__page)` is what keeps the cells out of it.
90
+ */
91
+ stepControls = this.locatorForAll(WrButtonHarness.with({ selector: '.wr-pagination__nav > wr-btn:not(.wr-pagination__page)' }));
92
+ /** Both kinds of strip slot, in DOM order — cells and the gaps between them. */
93
+ stripSlots = this.locatorForAll('.wr-pagination__page, .wr-pagination__ellipsis');
94
+ totalLabel = this.locatorForOptional('.wr-pagination__total');
95
+ sizeChanger = this.locatorForOptional(WrSelectHarness.with({ selector: '.wr-pagination__size' }));
96
+ /**
97
+ * The accessible name of the `role="navigation"` landmark.
98
+ *
99
+ * `''` only if the landmark lost its name, which is a bug rather than a state: a
100
+ * page with two unnamed pagers gives a screen-reader user two identical
101
+ * "navigation" landmarks.
102
+ */
103
+ async getLabel() {
104
+ return (await (await this.host()).getAttribute('aria-label')) ?? '';
105
+ }
106
+ /**
107
+ * The size the pager RENDERS at, from its host modifier.
108
+ *
109
+ * The modifier is always emitted — `sm` included — so the fall-through below is
110
+ * only ever reached for the default, and a size the strip is not wearing cannot
111
+ * come back from here.
112
+ *
113
+ * The STRIP resolves nothing through `provideWrConfig()`, which is worth knowing
114
+ * before an app-wide default is blamed for a cell size: the pager passes its own
115
+ * `size` down to every `<wr-btn>` explicitly, so a configured `button.size` never
116
+ * reaches a cell. The page-size changer is the exception and not covered by this
117
+ * value — it is a bare `<wr-select>`, so `provideWrConfig({ select: … })` does
118
+ * reach it.
119
+ */
120
+ async getSize() {
121
+ const host = await this.host();
122
+ if (await host.hasClass('wr-pagination--lg'))
123
+ return 'lg';
124
+ if (await host.hasClass('wr-pagination--md'))
125
+ return 'md';
126
+ return 'sm';
127
+ }
128
+ /**
129
+ * Whether the pager is ALLOWED to collapse into its compact pager.
130
+ *
131
+ * Whether it HAS collapsed is a container query on the control's own box, and a
132
+ * unit test has no layout for one to answer — assert this input in jsdom and the
133
+ * reflow itself in a real browser.
134
+ */
135
+ async isResponsive() {
136
+ return (await this.host()).hasClass('wr-pagination--responsive');
137
+ }
138
+ /**
139
+ * Whether the whole control refuses interaction.
140
+ *
141
+ * Read from the host modifier, because a `role="navigation"` landmark has no ARIA
142
+ * disabled state to prefer — the per-control answer lives on the buttons
143
+ * themselves (`disabled` plus `aria-disabled` on each), which is what
144
+ * {@link isPreviousDisabled} and {@link isNextDisabled} read.
145
+ */
146
+ async isDisabled() {
147
+ return (await this.host()).hasClass('wr-pagination--disabled');
148
+ }
149
+ /**
150
+ * The whole strip in DOM order: a `number` for every page cell, and the gap
151
+ * marker's own text (`…`) for every ellipsis.
152
+ *
153
+ * The marker is read from the DOM rather than compared against a literal, so a
154
+ * component that changes what it draws in a gap changes this too instead of
155
+ * quietly reporting a page.
156
+ */
157
+ async getStrip() {
158
+ const slots = await this.stripSlots();
159
+ return Promise.all(slots.map(async (slot) => {
160
+ const text = (await slot.text()).trim();
161
+ return (await slot.hasClass('wr-pagination__ellipsis')) ? text : Number(text);
162
+ }));
163
+ }
164
+ /**
165
+ * The pages that can be clicked right now, ascending. Gaps are not pages and are
166
+ * not here — `[1, 8, 9, 10, 11, 12, 20]` for a twenty-page list sitting on 10.
167
+ */
168
+ async getPages() {
169
+ const cells = await this.pageCells();
170
+ return Promise.all(cells.map(async (cell) => Number(await cell.getText())));
171
+ }
172
+ /**
173
+ * How many pages there are — not how many are on the strip.
174
+ *
175
+ * Taken from the LAST cell, which the window always pins to the final page (the
176
+ * first is pinned the same way), so this survives the gap that usually precedes
177
+ * it. Deliberately not read from the compact `3 / 10` pager: that span is
178
+ * `aria-hidden` and CSS-hidden outside responsive mode, so a browser-based
179
+ * harness environment would read it as empty.
180
+ */
181
+ async getTotalPages() {
182
+ const pages = await this.getPages();
183
+ const last = pages.at(-1);
184
+ if (last === undefined) {
185
+ throw new Error('WrPaginationHarness.getTotalPages(): the strip has no page cells at all. The pager offers page ' +
186
+ '1 even for an empty list, so this is a rendering failure rather than an empty state.');
187
+ }
188
+ return last;
189
+ }
190
+ /**
191
+ * The page the pager announces as current, from `aria-current="page"`.
192
+ *
193
+ * Throws when no cell claims it. The window always keeps the current page on the
194
+ * strip, so getting here means `currentPage` is not one of the pages at all — it
195
+ * is below 1, or not a whole number. The component clamps a page ABOVE the last
196
+ * one and nothing else, and either survivor leaves every cell looking equally
197
+ * inactive to an assistive tech user.
198
+ */
199
+ async getCurrentPage() {
200
+ const page = await this.currentPageOrNull();
201
+ if (page === null) {
202
+ throw new Error('WrPaginationHarness.getCurrentPage(): no cell carries `aria-current="page"`. The visible window ' +
203
+ `always includes the current page, so \`currentPage\` is not a page: below 1, or not a whole ` +
204
+ `number (the pager clamps above ${await this.getTotalPages()}, and nothing else).`);
205
+ }
206
+ return page;
207
+ }
208
+ /**
209
+ * Click the cell for a page.
210
+ *
211
+ * Throws when that page is not on the strip — a seven-slot window over twenty
212
+ * pages simply has no cell for page 15, and a silent no-op there reads as
213
+ * "navigation is broken" three assertions later. Step with {@link next} /
214
+ * {@link previous}, or move the host's own `currentPage` model.
215
+ *
216
+ * A disabled pager is still clicked; the component's own guard is what refuses
217
+ * the move, so assert the page rather than assume it. Clicking the CURRENT page
218
+ * is a no-op by the same guard.
219
+ */
220
+ async goToPage(page) {
221
+ for (const cell of await this.pageCells()) {
222
+ if (Number(await cell.getText()) === page) {
223
+ await cell.click();
224
+ return;
225
+ }
226
+ }
227
+ throw new Error(`WrPaginationHarness.goToPage(): page ${page} is not on the strip, which offers ` +
228
+ `${(await this.getStrip()).join(' ')}. The window shows at most seven pages — step with next() / ` +
229
+ 'previous(), or set the page on the host.');
230
+ }
231
+ /**
232
+ * Jump to page 1.
233
+ *
234
+ * There is no dedicated first / last control in this component; the window pins
235
+ * the first and last page to the ends of the strip instead, so these two click
236
+ * cells like any other page.
237
+ */
238
+ async goToFirst() {
239
+ return this.goToPage(1);
240
+ }
241
+ /** Jump to the last page — the trailing cell, not the last one before a gap. */
242
+ async goToLast() {
243
+ return this.goToPage(await this.getTotalPages());
244
+ }
245
+ /**
246
+ * Click the next-page control.
247
+ *
248
+ * Disabled on the last page, and a disabled `<wr-btn>` is still clicked here (see
249
+ * {@link goToPage}) — {@link isNextDisabled} is the question, this is the action.
250
+ */
251
+ async next() {
252
+ return (await this.stepControl('next')).click();
253
+ }
254
+ /** Click the previous-page control. Disabled on the first page. */
255
+ async previous() {
256
+ return (await this.stepControl('previous')).click();
257
+ }
258
+ /**
259
+ * Whether the next-page control refuses the move — true on the last page, and
260
+ * true for every control while the pager is disabled.
261
+ *
262
+ * Answered by {@link WrButtonHarness}, which reads the `disabled` attribute first
263
+ * and `aria-disabled` second. A `<wr-btn>` element carries both: the attribute is
264
+ * inert on anything but a real `<button>`, which is why the component adds the
265
+ * ARIA state as well — so this is the accessible answer whichever branch supplies
266
+ * it.
267
+ */
268
+ async isNextDisabled() {
269
+ return (await this.stepControl('next')).isDisabled();
270
+ }
271
+ /** Whether the previous-page control refuses the move — true on the first page. */
272
+ async isPreviousDisabled() {
273
+ return (await this.stepControl('previous')).isDisabled();
274
+ }
275
+ /** Whether the pager shows its "X–Y of Z" label (the `showTotal` input). */
276
+ async hasTotal() {
277
+ return (await this.totalLabel()) !== null;
278
+ }
279
+ /**
280
+ * The total label exactly as rendered, e.g. `1-10 of 95`.
281
+ *
282
+ * Both halves are localizable — the word between range and total comes from
283
+ * `ofLabel` or the `pagination.of` catalog entry — so a spec asserting the whole
284
+ * string should own the copy it asserts.
285
+ *
286
+ * Throws when the label is not rendered, which is a `showTotal` that was never
287
+ * set rather than a total of zero (a zero total still renders `0-0 of 0`).
288
+ */
289
+ async getTotalText() {
290
+ const label = await this.totalLabel();
291
+ if (!label) {
292
+ throw new Error('WrPaginationHarness.getTotalText(): this pager renders no total label — set `showTotal`. A ' +
293
+ 'total of 0 still renders one.');
294
+ }
295
+ return label.text();
296
+ }
297
+ /** Whether the pager renders its page-size changer (the `showSizeChanger` input). */
298
+ async hasPageSizeChanger() {
299
+ return (await this.sizeChanger()) !== null;
300
+ }
301
+ /**
302
+ * The page-size changer as a {@link WrSelectHarness} — for anything this harness
303
+ * does not wrap: the offered labels, the open state, keyboard driving.
304
+ *
305
+ * Composed rather than re-queried on purpose: the changer is a real
306
+ * `<wr-select>`, its options live in the overlay container rather than inside the
307
+ * pager, and the select harness is the thing that already knows how to scope them
308
+ * to their own trigger.
309
+ *
310
+ * Throws when there is no changer — an `undefined` here would turn into a
311
+ * confusing failure inside a select call.
312
+ */
313
+ async getPageSizeSelect() {
314
+ const select = await this.sizeChanger();
315
+ if (!select) {
316
+ throw new Error('WrPaginationHarness.getPageSizeSelect(): no page-size changer here — set `showSizeChanger`.');
317
+ }
318
+ return select;
319
+ }
320
+ /**
321
+ * The page size currently in effect.
322
+ *
323
+ * The changer's trigger is the only place the size reaches the DOM, so this reads
324
+ * it there and takes the digits: the label is localizable (`pagination.perPage`,
325
+ * `{{size}} / page`) but interpolates the number in every language — unless a
326
+ * catalog entry drops the placeholder, which is the second throw below.
327
+ *
328
+ * Throws when there is no changer at all: a pager without one says nothing on
329
+ * screen about its page size, and the host's own model is where to assert it.
330
+ */
331
+ async getPageSize() {
332
+ const text = await (await this.getPageSizeSelect()).getValueText();
333
+ const digits = /\d+/.exec(text);
334
+ if (!digits) {
335
+ throw new Error(`WrPaginationHarness.getPageSize(): the changer reads "${text}", which names no number — a ` +
336
+ 'catalog entry for `pagination.perPage` that drops `{{size}}` takes the size off the screen.');
337
+ }
338
+ return Number(digits[0]);
339
+ }
340
+ /**
341
+ * Pick a page size through the changer, the way a user does.
342
+ *
343
+ * Matched on the digits rather than the whole label, for the same reason
344
+ * {@link getPageSize} reads them: `20 / page` and `20 / стр.` are the same option.
345
+ * Throws when no option offers that size, naming what is on offer.
346
+ *
347
+ * Changing the size can move the page — the component pulls `currentPage` back
348
+ * when the new size leaves it past the end — so re-read {@link getCurrentPage}
349
+ * afterwards rather than assuming it held.
350
+ */
351
+ async setPageSize(size) {
352
+ const select = await this.getPageSizeSelect();
353
+ if (await this.isDisabled()) {
354
+ // Without this the call fails inside the select harness, whose message blames
355
+ // a tag-mode panel and a `minChars` search that have nothing to do with it.
356
+ throw new Error('WrPaginationHarness.setPageSize(): the pager is disabled, so its changer refuses to open — the ' +
357
+ 'pager hands its own `disabled` straight to it.');
358
+ }
359
+ await select.open();
360
+ const labels = await select.getOptionLabels();
361
+ const digits = new RegExp(`(^|\\D)${size}(\\D|$)`);
362
+ const match = labels.find(label => digits.test(label));
363
+ if (match === undefined) {
364
+ throw new Error(`WrPaginationHarness.setPageSize(): no option offers ${size} — the changer offers ` +
365
+ `${labels.join(', ')}. \`pageSizeOptions\` is what decides that list.`);
366
+ }
367
+ await select.selectOption({ text: match });
368
+ }
369
+ /** The current page, or `null` when no cell announces one. @see getCurrentPage */
370
+ async currentPageOrNull() {
371
+ const cell = await this.locatorForOptional(WrButtonHarness.with({ selector: '.wr-pagination__page[aria-current="page"]' }))();
372
+ return cell ? Number(await cell.getText()) : null;
373
+ }
374
+ async stepControl(which) {
375
+ const controls = await this.stepControls();
376
+ if (controls.length !== 2) {
377
+ throw new Error(`WrPaginationHarness: expected the nav to bracket the strip with a previous and a next control, ` +
378
+ `found ${controls.length}. They are addressed by position, since their labels are localizable.`);
379
+ }
380
+ return which === 'previous' ? controls[0] : controls[1];
381
+ }
382
+ }
383
+
384
+ /**
385
+ * Generated bundle index. Do not edit.
386
+ */
387
+
388
+ export { WrPaginationHarness };
389
+ //# sourceMappingURL=ngwr-pagination-testing.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ngwr-pagination-testing.mjs","sources":["../../../projects/lib/pagination/testing/wr-pagination-harness.ts","../../../projects/lib/pagination/testing/ngwr-pagination-testing.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';\n\nimport { WrButtonHarness } from 'ngwr/button/testing';\nimport type { WrPaginationSize } from 'ngwr/pagination';\nimport { WrSelectHarness } from 'ngwr/select/testing';\n\nimport type { WrPaginationHarnessFilters } from './interfaces';\n\n/**\n * Test harness for `<wr-pagination>` — the numbered strip, its two step controls,\n * the total label and the page-size changer.\n *\n * The strip is not the page list: it is a WINDOW over it, at most seven pages wide,\n * with an `…` standing in for every page it skipped. So \"which pages can I click\"\n * and \"how many pages are there\" are different questions and this harness keeps\n * them apart —\n * {@link getPages} answers the first, {@link getTotalPages} the second, and\n * {@link getStrip} shows the gaps for what they are. A gap is a `<span>`, not a\n * control; counting the strip's children as pages is the mistake this API exists to\n * make impossible.\n *\n * **Which page is current has two answers, and this reads the ARIA one.** The\n * current cell is also PAINTED — the template binds\n * `[color]=\"isCurrent(page) ? 'primary' : null\"`, so `.wr-btn--primary` sits on it\n * too. But colour is a theming decision (`ngwr/config` names this very binding as\n * the reason it ships no app-wide `color` default), while `aria-current=\"page\"` is\n * the navigation contract: it is what a screen-reader user hears, what the\n * component's own spec pins, and the only one of the two that still means\n * \"you are here\" after a restyle. A harness that read the class would be reporting\n * on the paint.\n *\n * **No roving tab stop to disambiguate.** Every cell is a `<wr-btn>` ELEMENT with\n * its own tab stop (`tabindex=\"0\"`, dropped only while the control is off), so the\n * pager has no separate \"focused\" item that could drift from the current page —\n * unlike a tab strip or a radio group, there is one active state here and\n * {@link getCurrentPage} is it.\n *\n * Composed rather than re-queried: the cells and step controls are driven through\n * {@link WrButtonHarness}, which already knows how a `<wr-btn>` says it is off —\n * both the `disabled` attribute (written on every shape, though inert on a custom\n * element) and `aria-disabled`, in that order — and the size changer through\n * {@link WrSelectHarness}, whose panel is a portal in the overlay container and\n * nowhere inside the pager.\n *\n * jsdom notes: every method here is a class / attribute read or a no-arg click, so\n * none of it needs layout. Two things are therefore invisible in a unit test and\n * deliberately absent from this API — the responsive collapse, which is a container\n * query ({@link isResponsive} reports only that it is ALLOWED), and the compact\n * `‹ 3 / 10 ›` pager it swaps in, which is `aria-hidden` decoration duplicating\n * {@link getCurrentPage} and {@link getTotalPages} and which a real browser would\n * read as empty text while CSS keeps it hidden.\n *\n * @example\n * ```ts\n * const pager = await loader.getHarness(WrPaginationHarness);\n *\n * expect(await pager.getPages()).toEqual([1, 2, 3, 4, 5, 10]);\n * await pager.goToPage(3);\n * expect(await pager.getCurrentPage()).toBe(3);\n * ```\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrPaginationHarness extends ComponentHarness {\n static hostSelector = 'wr-pagination';\n\n /** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */\n static with(options: WrPaginationHarnessFilters = {}): HarnessPredicate<WrPaginationHarness> {\n return new HarnessPredicate(WrPaginationHarness, options)\n .addOption('label', options.label, (harness, label) => HarnessPredicate.stringMatches(harness.getLabel(), label))\n .addOption('currentPage', options.currentPage, async (harness, page) => {\n // The nullable read on purpose: the throwing getter would reject the whole\n // query over one pager that announces no current page, taking its\n // well-behaved neighbours down with it.\n return (await harness.currentPageOrNull()) === page;\n })\n .addOption('disabled', options.disabled, async (harness, disabled) => (await harness.isDisabled()) === disabled);\n }\n\n /** The numbered cells, in DOM order — ascending, and never a gap. */\n private readonly pageCells = this.locatorForAll(WrButtonHarness.with({ selector: '.wr-pagination__page' }));\n\n /**\n * The two controls bracketing the strip: previous, then next.\n *\n * Located by POSITION, not by their labels. `prevLabel` / `nextLabel` are inputs\n * and both fall back to the `pagination.prev` / `pagination.next` catalog entries,\n * so an English `aria-label` match works right up until someone ships a locale —\n * whereas the nav's shape (one step control, the strip, one step control) is\n * structural. `:not(.wr-pagination__page)` is what keeps the cells out of it.\n */\n private readonly stepControls = this.locatorForAll(\n WrButtonHarness.with({ selector: '.wr-pagination__nav > wr-btn:not(.wr-pagination__page)' })\n );\n\n /** Both kinds of strip slot, in DOM order — cells and the gaps between them. */\n private readonly stripSlots = this.locatorForAll('.wr-pagination__page, .wr-pagination__ellipsis');\n\n private readonly totalLabel = this.locatorForOptional('.wr-pagination__total');\n\n private readonly sizeChanger = this.locatorForOptional(WrSelectHarness.with({ selector: '.wr-pagination__size' }));\n\n /**\n * The accessible name of the `role=\"navigation\"` landmark.\n *\n * `''` only if the landmark lost its name, which is a bug rather than a state: a\n * page with two unnamed pagers gives a screen-reader user two identical\n * \"navigation\" landmarks.\n */\n async getLabel(): Promise<string> {\n return (await (await this.host()).getAttribute('aria-label')) ?? '';\n }\n\n /**\n * The size the pager RENDERS at, from its host modifier.\n *\n * The modifier is always emitted — `sm` included — so the fall-through below is\n * only ever reached for the default, and a size the strip is not wearing cannot\n * come back from here.\n *\n * The STRIP resolves nothing through `provideWrConfig()`, which is worth knowing\n * before an app-wide default is blamed for a cell size: the pager passes its own\n * `size` down to every `<wr-btn>` explicitly, so a configured `button.size` never\n * reaches a cell. The page-size changer is the exception and not covered by this\n * value — it is a bare `<wr-select>`, so `provideWrConfig({ select: … })` does\n * reach it.\n */\n async getSize(): Promise<WrPaginationSize> {\n const host = await this.host();\n if (await host.hasClass('wr-pagination--lg')) return 'lg';\n if (await host.hasClass('wr-pagination--md')) return 'md';\n return 'sm';\n }\n\n /**\n * Whether the pager is ALLOWED to collapse into its compact pager.\n *\n * Whether it HAS collapsed is a container query on the control's own box, and a\n * unit test has no layout for one to answer — assert this input in jsdom and the\n * reflow itself in a real browser.\n */\n async isResponsive(): Promise<boolean> {\n return (await this.host()).hasClass('wr-pagination--responsive');\n }\n\n /**\n * Whether the whole control refuses interaction.\n *\n * Read from the host modifier, because a `role=\"navigation\"` landmark has no ARIA\n * disabled state to prefer — the per-control answer lives on the buttons\n * themselves (`disabled` plus `aria-disabled` on each), which is what\n * {@link isPreviousDisabled} and {@link isNextDisabled} read.\n */\n async isDisabled(): Promise<boolean> {\n return (await this.host()).hasClass('wr-pagination--disabled');\n }\n\n /**\n * The whole strip in DOM order: a `number` for every page cell, and the gap\n * marker's own text (`…`) for every ellipsis.\n *\n * The marker is read from the DOM rather than compared against a literal, so a\n * component that changes what it draws in a gap changes this too instead of\n * quietly reporting a page.\n */\n async getStrip(): Promise<(number | string)[]> {\n const slots = await this.stripSlots();\n return Promise.all(\n slots.map(async slot => {\n const text = (await slot.text()).trim();\n return (await slot.hasClass('wr-pagination__ellipsis')) ? text : Number(text);\n })\n );\n }\n\n /**\n * The pages that can be clicked right now, ascending. Gaps are not pages and are\n * not here — `[1, 8, 9, 10, 11, 12, 20]` for a twenty-page list sitting on 10.\n */\n async getPages(): Promise<number[]> {\n const cells = await this.pageCells();\n return Promise.all(cells.map(async cell => Number(await cell.getText())));\n }\n\n /**\n * How many pages there are — not how many are on the strip.\n *\n * Taken from the LAST cell, which the window always pins to the final page (the\n * first is pinned the same way), so this survives the gap that usually precedes\n * it. Deliberately not read from the compact `3 / 10` pager: that span is\n * `aria-hidden` and CSS-hidden outside responsive mode, so a browser-based\n * harness environment would read it as empty.\n */\n async getTotalPages(): Promise<number> {\n const pages = await this.getPages();\n const last = pages.at(-1);\n if (last === undefined) {\n throw new Error(\n 'WrPaginationHarness.getTotalPages(): the strip has no page cells at all. The pager offers page ' +\n '1 even for an empty list, so this is a rendering failure rather than an empty state.'\n );\n }\n return last;\n }\n\n /**\n * The page the pager announces as current, from `aria-current=\"page\"`.\n *\n * Throws when no cell claims it. The window always keeps the current page on the\n * strip, so getting here means `currentPage` is not one of the pages at all — it\n * is below 1, or not a whole number. The component clamps a page ABOVE the last\n * one and nothing else, and either survivor leaves every cell looking equally\n * inactive to an assistive tech user.\n */\n async getCurrentPage(): Promise<number> {\n const page = await this.currentPageOrNull();\n if (page === null) {\n throw new Error(\n 'WrPaginationHarness.getCurrentPage(): no cell carries `aria-current=\"page\"`. The visible window ' +\n `always includes the current page, so \\`currentPage\\` is not a page: below 1, or not a whole ` +\n `number (the pager clamps above ${await this.getTotalPages()}, and nothing else).`\n );\n }\n return page;\n }\n\n /**\n * Click the cell for a page.\n *\n * Throws when that page is not on the strip — a seven-slot window over twenty\n * pages simply has no cell for page 15, and a silent no-op there reads as\n * \"navigation is broken\" three assertions later. Step with {@link next} /\n * {@link previous}, or move the host's own `currentPage` model.\n *\n * A disabled pager is still clicked; the component's own guard is what refuses\n * the move, so assert the page rather than assume it. Clicking the CURRENT page\n * is a no-op by the same guard.\n */\n async goToPage(page: number): Promise<void> {\n for (const cell of await this.pageCells()) {\n if (Number(await cell.getText()) === page) {\n await cell.click();\n return;\n }\n }\n\n throw new Error(\n `WrPaginationHarness.goToPage(): page ${page} is not on the strip, which offers ` +\n `${(await this.getStrip()).join(' ')}. The window shows at most seven pages — step with next() / ` +\n 'previous(), or set the page on the host.'\n );\n }\n\n /**\n * Jump to page 1.\n *\n * There is no dedicated first / last control in this component; the window pins\n * the first and last page to the ends of the strip instead, so these two click\n * cells like any other page.\n */\n async goToFirst(): Promise<void> {\n return this.goToPage(1);\n }\n\n /** Jump to the last page — the trailing cell, not the last one before a gap. */\n async goToLast(): Promise<void> {\n return this.goToPage(await this.getTotalPages());\n }\n\n /**\n * Click the next-page control.\n *\n * Disabled on the last page, and a disabled `<wr-btn>` is still clicked here (see\n * {@link goToPage}) — {@link isNextDisabled} is the question, this is the action.\n */\n async next(): Promise<void> {\n return (await this.stepControl('next')).click();\n }\n\n /** Click the previous-page control. Disabled on the first page. */\n async previous(): Promise<void> {\n return (await this.stepControl('previous')).click();\n }\n\n /**\n * Whether the next-page control refuses the move — true on the last page, and\n * true for every control while the pager is disabled.\n *\n * Answered by {@link WrButtonHarness}, which reads the `disabled` attribute first\n * and `aria-disabled` second. A `<wr-btn>` element carries both: the attribute is\n * inert on anything but a real `<button>`, which is why the component adds the\n * ARIA state as well — so this is the accessible answer whichever branch supplies\n * it.\n */\n async isNextDisabled(): Promise<boolean> {\n return (await this.stepControl('next')).isDisabled();\n }\n\n /** Whether the previous-page control refuses the move — true on the first page. */\n async isPreviousDisabled(): Promise<boolean> {\n return (await this.stepControl('previous')).isDisabled();\n }\n\n /** Whether the pager shows its \"X–Y of Z\" label (the `showTotal` input). */\n async hasTotal(): Promise<boolean> {\n return (await this.totalLabel()) !== null;\n }\n\n /**\n * The total label exactly as rendered, e.g. `1-10 of 95`.\n *\n * Both halves are localizable — the word between range and total comes from\n * `ofLabel` or the `pagination.of` catalog entry — so a spec asserting the whole\n * string should own the copy it asserts.\n *\n * Throws when the label is not rendered, which is a `showTotal` that was never\n * set rather than a total of zero (a zero total still renders `0-0 of 0`).\n */\n async getTotalText(): Promise<string> {\n const label = await this.totalLabel();\n if (!label) {\n throw new Error(\n 'WrPaginationHarness.getTotalText(): this pager renders no total label — set `showTotal`. A ' +\n 'total of 0 still renders one.'\n );\n }\n return label.text();\n }\n\n /** Whether the pager renders its page-size changer (the `showSizeChanger` input). */\n async hasPageSizeChanger(): Promise<boolean> {\n return (await this.sizeChanger()) !== null;\n }\n\n /**\n * The page-size changer as a {@link WrSelectHarness} — for anything this harness\n * does not wrap: the offered labels, the open state, keyboard driving.\n *\n * Composed rather than re-queried on purpose: the changer is a real\n * `<wr-select>`, its options live in the overlay container rather than inside the\n * pager, and the select harness is the thing that already knows how to scope them\n * to their own trigger.\n *\n * Throws when there is no changer — an `undefined` here would turn into a\n * confusing failure inside a select call.\n */\n async getPageSizeSelect(): Promise<WrSelectHarness> {\n const select = await this.sizeChanger();\n if (!select) {\n throw new Error('WrPaginationHarness.getPageSizeSelect(): no page-size changer here — set `showSizeChanger`.');\n }\n return select;\n }\n\n /**\n * The page size currently in effect.\n *\n * The changer's trigger is the only place the size reaches the DOM, so this reads\n * it there and takes the digits: the label is localizable (`pagination.perPage`,\n * `{{size}} / page`) but interpolates the number in every language — unless a\n * catalog entry drops the placeholder, which is the second throw below.\n *\n * Throws when there is no changer at all: a pager without one says nothing on\n * screen about its page size, and the host's own model is where to assert it.\n */\n async getPageSize(): Promise<number> {\n const text = await (await this.getPageSizeSelect()).getValueText();\n const digits = /\\d+/.exec(text);\n if (!digits) {\n throw new Error(\n `WrPaginationHarness.getPageSize(): the changer reads \"${text}\", which names no number — a ` +\n 'catalog entry for `pagination.perPage` that drops `{{size}}` takes the size off the screen.'\n );\n }\n return Number(digits[0]);\n }\n\n /**\n * Pick a page size through the changer, the way a user does.\n *\n * Matched on the digits rather than the whole label, for the same reason\n * {@link getPageSize} reads them: `20 / page` and `20 / стр.` are the same option.\n * Throws when no option offers that size, naming what is on offer.\n *\n * Changing the size can move the page — the component pulls `currentPage` back\n * when the new size leaves it past the end — so re-read {@link getCurrentPage}\n * afterwards rather than assuming it held.\n */\n async setPageSize(size: number): Promise<void> {\n const select = await this.getPageSizeSelect();\n if (await this.isDisabled()) {\n // Without this the call fails inside the select harness, whose message blames\n // a tag-mode panel and a `minChars` search that have nothing to do with it.\n throw new Error(\n 'WrPaginationHarness.setPageSize(): the pager is disabled, so its changer refuses to open — the ' +\n 'pager hands its own `disabled` straight to it.'\n );\n }\n\n await select.open();\n\n const labels = await select.getOptionLabels();\n const digits = new RegExp(`(^|\\\\D)${size}(\\\\D|$)`);\n const match = labels.find(label => digits.test(label));\n if (match === undefined) {\n throw new Error(\n `WrPaginationHarness.setPageSize(): no option offers ${size} — the changer offers ` +\n `${labels.join(', ')}. \\`pageSizeOptions\\` is what decides that list.`\n );\n }\n\n await select.selectOption({ text: match });\n }\n\n /** The current page, or `null` when no cell announces one. @see getCurrentPage */\n private async currentPageOrNull(): Promise<number | null> {\n const cell = await this.locatorForOptional(\n WrButtonHarness.with({ selector: '.wr-pagination__page[aria-current=\"page\"]' })\n )();\n return cell ? Number(await cell.getText()) : null;\n }\n\n private async stepControl(which: 'previous' | 'next'): Promise<WrButtonHarness> {\n const controls = await this.stepControls();\n if (controls.length !== 2) {\n throw new Error(\n `WrPaginationHarness: expected the nav to bracket the strip with a previous and a next control, ` +\n `found ${controls.length}. They are addressed by position, since their labels are localizable.`\n );\n }\n return which === 'previous' ? controls[0] : controls[1];\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -1,8 +1,6 @@
1
1
  import { coerceBooleanProperty } from '@angular/cdk/coercion';
2
2
  import * as i0 from '@angular/core';
3
- import { model, input, computed, ViewEncapsulation, Component } from '@angular/core';
4
- import * as i1 from '@angular/forms';
5
- import { FormsModule } from '@angular/forms';
3
+ import { model, input, computed, effect, untracked, ViewEncapsulation, Component } from '@angular/core';
6
4
  import { WrButton } from 'ngwr/button';
7
5
  import { useI18nText, useI18nFormatter } from 'ngwr/i18n';
8
6
  import { WrSelect, WrOption } from 'ngwr/select';
@@ -168,21 +166,39 @@ class WrPagination {
168
166
  return;
169
167
  this.currentPage.set(page);
170
168
  }
169
+ /**
170
+ * `wr-select` carries an `unknown` value by design, so the size arrives
171
+ * untyped and is narrowed here. It used to arrive as `any` through
172
+ * `[ngModel]`, which hid the coercion rather than removing the need for it.
173
+ */
174
+ constructor() {
175
+ // A shrinking `total` must not leave the pager on a page that no longer
176
+ // exists: it only ever pulled back when the SIZE changed through its own
177
+ // control, so a filtered list left "page 7 of 2" pointing at nothing.
178
+ effect(() => {
179
+ const cap = this.totalPages();
180
+ untracked(() => {
181
+ if (this.currentPage() > cap)
182
+ this.currentPage.set(cap);
183
+ });
184
+ });
185
+ }
171
186
  onSizeChange(size) {
172
- if (this.disabled() || size === this.pageSize())
187
+ const next = Number(size);
188
+ if (this.disabled() || !Number.isFinite(next) || next <= 0 || next === this.pageSize())
173
189
  return;
174
- this.pageSize.set(size);
175
- const cap = Math.max(1, Math.ceil(this.total() / size));
190
+ this.pageSize.set(next);
191
+ const cap = Math.max(1, Math.ceil(this.total() / next));
176
192
  if (this.currentPage() > cap)
177
193
  this.currentPage.set(cap);
178
194
  }
179
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: WrPagination, deps: [], target: i0.ɵɵFactoryTarget.Component });
180
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.0", type: WrPagination, isStandalone: true, selector: "wr-pagination", inputs: { currentPage: { classPropertyName: "currentPage", publicName: "currentPage", 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 }, ofLabel: { classPropertyName: "ofLabel", publicName: "ofLabel", 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: { currentPage: "currentPageChange", 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 <wr-btn\n [size]=\"size()\"\n outlined\n [attr.aria-label]=\"resolvedPrev()\"\n [disabled]=\"disabled() || currentPage() === 1\"\n (click)=\"goTo(currentPage() - 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=\"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\">{{ currentPage() }} / {{ totalPages() }}</span>\n\n <wr-btn\n [size]=\"size()\"\n outlined\n [attr.aria-label]=\"resolvedNext()\"\n [disabled]=\"disabled() || currentPage() === totalPages()\"\n (click)=\"goTo(currentPage() + 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 <wr-select\n class=\"wr-pagination__size\"\n [attr.aria-label]=\"resolvedItemsPerPage()\"\n [disabled]=\"disabled()\"\n [ngModel]=\"pageSize()\"\n (ngModelChange)=\"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: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: WrButton, selector: "wr-btn, button[wr-btn], a[wr-btn]", inputs: ["color", "size", "shape", "icon", "iconPosition", "disabled", "outlined", "block", "loading", "isDisabledWhenLoading"] }, { kind: "component", type: WrSelect, selector: "wr-select", inputs: ["placeholder", "clearLabel", "ariaLabel", "disabled", "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 });
195
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: WrPagination, deps: [], target: i0.ɵɵFactoryTarget.Component });
196
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.1", type: WrPagination, isStandalone: true, selector: "wr-pagination", inputs: { currentPage: { classPropertyName: "currentPage", publicName: "currentPage", 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 }, ofLabel: { classPropertyName: "ofLabel", publicName: "ofLabel", 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: { currentPage: "currentPageChange", 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 <wr-btn\n [size]=\"size()\"\n outlined\n [attr.aria-label]=\"resolvedPrev()\"\n [disabled]=\"disabled() || currentPage() === 1\"\n (click)=\"goTo(currentPage() - 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=\"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\">{{ currentPage() }} / {{ totalPages() }}</span>\n\n <wr-btn\n [size]=\"size()\"\n outlined\n [attr.aria-label]=\"resolvedNext()\"\n [disabled]=\"disabled() || currentPage() === totalPages()\"\n (click)=\"goTo(currentPage() + 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 <wr-select\n class=\"wr-pagination__size\"\n [attr.aria-label]=\"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", "isDisabledWhenLoading"] }, { kind: "component", type: WrSelect, selector: "wr-select", inputs: ["placeholder", "clearLabel", "ariaLabel", "disabled", "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 });
181
197
  }
182
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.0", ngImport: i0, type: WrPagination, decorators: [{
198
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: WrPagination, decorators: [{
183
199
  type: Component,
184
- args: [{ selector: 'wr-pagination', encapsulation: ViewEncapsulation.None, host: { '[class]': 'classes()', role: 'navigation', '[attr.aria-label]': 'navLabel()' }, imports: [FormsModule, 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 <wr-btn\n [size]=\"size()\"\n outlined\n [attr.aria-label]=\"resolvedPrev()\"\n [disabled]=\"disabled() || currentPage() === 1\"\n (click)=\"goTo(currentPage() - 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=\"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\">{{ currentPage() }} / {{ totalPages() }}</span>\n\n <wr-btn\n [size]=\"size()\"\n outlined\n [attr.aria-label]=\"resolvedNext()\"\n [disabled]=\"disabled() || currentPage() === totalPages()\"\n (click)=\"goTo(currentPage() + 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 <wr-select\n class=\"wr-pagination__size\"\n [attr.aria-label]=\"resolvedItemsPerPage()\"\n [disabled]=\"disabled()\"\n [ngModel]=\"pageSize()\"\n (ngModelChange)=\"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" }]
185
- }], propDecorators: { currentPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentPage", required: false }] }, { type: i0.Output, args: ["currentPageChange"] }], 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 }] }], ofLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ofLabel", 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 }] }] } });
200
+ 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 <wr-btn\n [size]=\"size()\"\n outlined\n [attr.aria-label]=\"resolvedPrev()\"\n [disabled]=\"disabled() || currentPage() === 1\"\n (click)=\"goTo(currentPage() - 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=\"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\">{{ currentPage() }} / {{ totalPages() }}</span>\n\n <wr-btn\n [size]=\"size()\"\n outlined\n [attr.aria-label]=\"resolvedNext()\"\n [disabled]=\"disabled() || currentPage() === totalPages()\"\n (click)=\"goTo(currentPage() + 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 <wr-select\n class=\"wr-pagination__size\"\n [attr.aria-label]=\"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" }]
201
+ }], ctorParameters: () => [], propDecorators: { currentPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentPage", required: false }] }, { type: i0.Output, args: ["currentPageChange"] }], 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 }] }], ofLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ofLabel", 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 }] }] } });
186
202
 
187
203
  /**
188
204
  * Generated bundle index. Do not edit.