ngwr 11.2.0 → 12.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 (394) hide show
  1. package/README.md +7 -7
  2. package/burger/styles/_index.scss +1 -1
  3. package/button/styles/_index.scss +2 -2
  4. package/calendar/styles/_index.scss +32 -12
  5. package/calendar-heatmap/styles/_index.scss +20 -0
  6. package/carousel/styles/_index.scss +23 -1
  7. package/cascader/styles/_index.scss +15 -3
  8. package/checkbox/styles/_index.scss +2 -2
  9. package/collapse/styles/_index.scss +2 -2
  10. package/color-picker/styles/_index.scss +3 -3
  11. package/compare/styles/_index.scss +18 -2
  12. package/context-menu/styles/_index.scss +21 -2
  13. package/date-picker/styles/_index.scss +5 -5
  14. package/descriptions/styles/_index.scss +1 -1
  15. package/drag-drop/styles/_index.scss +28 -1
  16. package/drawer/styles/_index.scss +37 -0
  17. package/dropdown/styles/_index.scss +2 -2
  18. package/event-calendar/styles/_index.scss +67 -10
  19. package/fesm2022/ngwr-action-sheet.mjs +3 -3
  20. package/fesm2022/ngwr-affix.mjs +3 -3
  21. package/fesm2022/ngwr-alert.mjs +3 -3
  22. package/fesm2022/ngwr-anchor.mjs +3 -3
  23. package/fesm2022/ngwr-aurora.mjs +3 -3
  24. package/fesm2022/ngwr-avatar.mjs +3 -3
  25. package/fesm2022/ngwr-back-top.mjs +3 -3
  26. package/fesm2022/ngwr-badge.mjs +6 -6
  27. package/fesm2022/ngwr-bar-chart-testing.mjs +20 -2
  28. package/fesm2022/ngwr-bar-chart-testing.mjs.map +1 -1
  29. package/fesm2022/ngwr-bar-chart.mjs +3 -3
  30. package/fesm2022/ngwr-blur-text.mjs +3 -3
  31. package/fesm2022/ngwr-blur-text.mjs.map +1 -1
  32. package/fesm2022/ngwr-border-glow.mjs +4 -4
  33. package/fesm2022/ngwr-border-glow.mjs.map +1 -1
  34. package/fesm2022/ngwr-breadcrumbs.mjs +29 -17
  35. package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
  36. package/fesm2022/ngwr-burger.mjs +3 -3
  37. package/fesm2022/ngwr-button.mjs +6 -6
  38. package/fesm2022/ngwr-calendar-heatmap.mjs +17 -5
  39. package/fesm2022/ngwr-calendar-heatmap.mjs.map +1 -1
  40. package/fesm2022/ngwr-calendar-testing.mjs +1 -1
  41. package/fesm2022/ngwr-calendar-testing.mjs.map +1 -1
  42. package/fesm2022/ngwr-calendar.mjs +187 -9
  43. package/fesm2022/ngwr-calendar.mjs.map +1 -1
  44. package/fesm2022/ngwr-card.mjs +10 -10
  45. package/fesm2022/ngwr-card.mjs.map +1 -1
  46. package/fesm2022/ngwr-carousel.mjs +124 -24
  47. package/fesm2022/ngwr-carousel.mjs.map +1 -1
  48. package/fesm2022/ngwr-cascader.mjs +48 -5
  49. package/fesm2022/ngwr-cascader.mjs.map +1 -1
  50. package/fesm2022/ngwr-checkbox.mjs +6 -6
  51. package/fesm2022/ngwr-circular-text.mjs +4 -4
  52. package/fesm2022/ngwr-circular-text.mjs.map +1 -1
  53. package/fesm2022/ngwr-click-spark.mjs +27 -7
  54. package/fesm2022/ngwr-click-spark.mjs.map +1 -1
  55. package/fesm2022/ngwr-clipboard.mjs +3 -3
  56. package/fesm2022/ngwr-collapse.mjs +9 -9
  57. package/fesm2022/ngwr-color-picker-testing.mjs +26 -6
  58. package/fesm2022/ngwr-color-picker-testing.mjs.map +1 -1
  59. package/fesm2022/ngwr-color-picker.mjs +98 -8
  60. package/fesm2022/ngwr-color-picker.mjs.map +1 -1
  61. package/fesm2022/ngwr-command-palette.mjs +14 -5
  62. package/fesm2022/ngwr-command-palette.mjs.map +1 -1
  63. package/fesm2022/ngwr-compare.mjs +3 -3
  64. package/fesm2022/ngwr-confetti.mjs +31 -6
  65. package/fesm2022/ngwr-confetti.mjs.map +1 -1
  66. package/fesm2022/ngwr-config.mjs +9 -0
  67. package/fesm2022/ngwr-config.mjs.map +1 -1
  68. package/fesm2022/ngwr-context-menu-testing.mjs +30 -11
  69. package/fesm2022/ngwr-context-menu-testing.mjs.map +1 -1
  70. package/fesm2022/ngwr-context-menu.mjs +333 -43
  71. package/fesm2022/ngwr-context-menu.mjs.map +1 -1
  72. package/fesm2022/ngwr-cookie.mjs +3 -3
  73. package/fesm2022/ngwr-counter.mjs +25 -9
  74. package/fesm2022/ngwr-counter.mjs.map +1 -1
  75. package/fesm2022/{ngwr-date-adapter-fns.mjs → ngwr-date-adapters-fns.mjs} +37 -10
  76. package/fesm2022/ngwr-date-adapters-fns.mjs.map +1 -0
  77. package/fesm2022/{ngwr-date-adapter-luxon.mjs → ngwr-date-adapters-luxon.mjs} +5 -5
  78. package/fesm2022/ngwr-date-adapters-luxon.mjs.map +1 -0
  79. package/fesm2022/ngwr-date-picker-testing.mjs +11 -6
  80. package/fesm2022/ngwr-date-picker-testing.mjs.map +1 -1
  81. package/fesm2022/ngwr-date-picker.mjs +119 -37
  82. package/fesm2022/ngwr-date-picker.mjs.map +1 -1
  83. package/fesm2022/{ngwr-date-adapter.mjs → ngwr-date.mjs} +36 -10
  84. package/fesm2022/ngwr-date.mjs.map +1 -0
  85. package/fesm2022/ngwr-decrypt-text.mjs +3 -3
  86. package/fesm2022/ngwr-density.mjs +6 -6
  87. package/fesm2022/ngwr-descriptions.mjs +6 -6
  88. package/fesm2022/ngwr-dialog.mjs +73 -18
  89. package/fesm2022/ngwr-dialog.mjs.map +1 -1
  90. package/fesm2022/ngwr-directives.mjs +12 -12
  91. package/fesm2022/ngwr-divider.mjs +52 -5
  92. package/fesm2022/ngwr-divider.mjs.map +1 -1
  93. package/fesm2022/ngwr-donut-chart-testing.mjs +8 -4
  94. package/fesm2022/ngwr-donut-chart-testing.mjs.map +1 -1
  95. package/fesm2022/ngwr-donut-chart.mjs +7 -7
  96. package/fesm2022/ngwr-donut-chart.mjs.map +1 -1
  97. package/fesm2022/ngwr-drag-drop.mjs +160 -11
  98. package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
  99. package/fesm2022/ngwr-drawer.mjs +121 -58
  100. package/fesm2022/ngwr-drawer.mjs.map +1 -1
  101. package/fesm2022/ngwr-dropdown.mjs +26 -10
  102. package/fesm2022/ngwr-dropdown.mjs.map +1 -1
  103. package/fesm2022/ngwr-empty.mjs +3 -3
  104. package/fesm2022/ngwr-event-calendar.mjs +28 -15
  105. package/fesm2022/ngwr-event-calendar.mjs.map +1 -1
  106. package/fesm2022/ngwr-falling-text-testing.mjs +5 -3
  107. package/fesm2022/ngwr-falling-text-testing.mjs.map +1 -1
  108. package/fesm2022/ngwr-falling-text.mjs +75 -46
  109. package/fesm2022/ngwr-falling-text.mjs.map +1 -1
  110. package/fesm2022/ngwr-file-upload.mjs +3 -3
  111. package/fesm2022/ngwr-form.mjs +32 -15
  112. package/fesm2022/ngwr-form.mjs.map +1 -1
  113. package/fesm2022/ngwr-fuzzy-text.mjs +21 -11
  114. package/fesm2022/ngwr-fuzzy-text.mjs.map +1 -1
  115. package/fesm2022/ngwr-gauge.mjs +3 -3
  116. package/fesm2022/ngwr-glitch-text-testing.mjs +51 -17
  117. package/fesm2022/ngwr-glitch-text-testing.mjs.map +1 -1
  118. package/fesm2022/ngwr-glitch-text.mjs +7 -7
  119. package/fesm2022/ngwr-glitch-text.mjs.map +1 -1
  120. package/fesm2022/ngwr-gradient-text-testing.mjs +46 -11
  121. package/fesm2022/ngwr-gradient-text-testing.mjs.map +1 -1
  122. package/fesm2022/ngwr-gradient-text.mjs +4 -4
  123. package/fesm2022/ngwr-gradient-text.mjs.map +1 -1
  124. package/fesm2022/ngwr-hotkey.mjs +24 -9
  125. package/fesm2022/ngwr-hotkey.mjs.map +1 -1
  126. package/fesm2022/ngwr-i18n-en.mjs +73 -1
  127. package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
  128. package/fesm2022/ngwr-i18n-ru.mjs +55 -1
  129. package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
  130. package/fesm2022/ngwr-i18n.mjs +26 -15
  131. package/fesm2022/ngwr-i18n.mjs.map +1 -1
  132. package/fesm2022/ngwr-icon.mjs +6 -6
  133. package/fesm2022/ngwr-image-cropper-testing.mjs +53 -9
  134. package/fesm2022/ngwr-image-cropper-testing.mjs.map +1 -1
  135. package/fesm2022/ngwr-image-cropper.mjs +150 -12
  136. package/fesm2022/ngwr-image-cropper.mjs.map +1 -1
  137. package/fesm2022/ngwr-input-number-testing.mjs +15 -10
  138. package/fesm2022/ngwr-input-number-testing.mjs.map +1 -1
  139. package/fesm2022/ngwr-input-number.mjs +17 -10
  140. package/fesm2022/ngwr-input-number.mjs.map +1 -1
  141. package/fesm2022/ngwr-input-otp-testing.mjs +12 -6
  142. package/fesm2022/ngwr-input-otp-testing.mjs.map +1 -1
  143. package/fesm2022/ngwr-input-otp.mjs +24 -5
  144. package/fesm2022/ngwr-input-otp.mjs.map +1 -1
  145. package/fesm2022/ngwr-input.mjs +15 -15
  146. package/fesm2022/ngwr-keyboard.mjs +3 -3
  147. package/fesm2022/ngwr-knob.mjs +3 -3
  148. package/fesm2022/ngwr-layout.mjs +15 -15
  149. package/fesm2022/ngwr-lightbox.mjs +4 -4
  150. package/fesm2022/ngwr-lightbox.mjs.map +1 -1
  151. package/fesm2022/ngwr-line-chart.mjs +73 -26
  152. package/fesm2022/ngwr-line-chart.mjs.map +1 -1
  153. package/fesm2022/ngwr-list.mjs +7 -7
  154. package/fesm2022/ngwr-list.mjs.map +1 -1
  155. package/fesm2022/ngwr-loading-bar.mjs +7 -7
  156. package/fesm2022/ngwr-loading-bar.mjs.map +1 -1
  157. package/fesm2022/ngwr-markdown.mjs +66 -8
  158. package/fesm2022/ngwr-markdown.mjs.map +1 -1
  159. package/fesm2022/ngwr-marquee.mjs +4 -4
  160. package/fesm2022/ngwr-marquee.mjs.map +1 -1
  161. package/fesm2022/ngwr-media.mjs +3 -3
  162. package/fesm2022/ngwr-mention.mjs +108 -13
  163. package/fesm2022/ngwr-mention.mjs.map +1 -1
  164. package/fesm2022/ngwr-meta.mjs +6 -6
  165. package/fesm2022/ngwr-meter-group-testing.mjs +26 -6
  166. package/fesm2022/ngwr-meter-group-testing.mjs.map +1 -1
  167. package/fesm2022/ngwr-meter-group.mjs +3 -3
  168. package/fesm2022/ngwr-overlay.mjs +6 -6
  169. package/fesm2022/ngwr-page-header.mjs +3 -3
  170. package/fesm2022/ngwr-pagination-testing.mjs +6 -6
  171. package/fesm2022/ngwr-pagination-testing.mjs.map +1 -1
  172. package/fesm2022/ngwr-pagination.mjs +17 -13
  173. package/fesm2022/ngwr-pagination.mjs.map +1 -1
  174. package/fesm2022/ngwr-pipes.mjs +39 -26
  175. package/fesm2022/ngwr-pipes.mjs.map +1 -1
  176. package/fesm2022/ngwr-platform.mjs +9 -9
  177. package/fesm2022/ngwr-popconfirm.mjs +6 -6
  178. package/fesm2022/ngwr-popover-testing.mjs +7 -2
  179. package/fesm2022/ngwr-popover-testing.mjs.map +1 -1
  180. package/fesm2022/ngwr-popover.mjs +155 -33
  181. package/fesm2022/ngwr-popover.mjs.map +1 -1
  182. package/fesm2022/ngwr-progress.mjs +3 -3
  183. package/fesm2022/ngwr-pull-to-refresh.mjs +3 -3
  184. package/fesm2022/ngwr-qr.mjs +42 -5
  185. package/fesm2022/ngwr-qr.mjs.map +1 -1
  186. package/fesm2022/ngwr-radio.mjs +6 -6
  187. package/fesm2022/ngwr-rating.mjs +3 -3
  188. package/fesm2022/ngwr-result.mjs +21 -30
  189. package/fesm2022/ngwr-result.mjs.map +1 -1
  190. package/fesm2022/ngwr-rotating-text.mjs +3 -3
  191. package/fesm2022/ngwr-scroll.mjs +3 -3
  192. package/fesm2022/ngwr-segmented-testing.mjs +14 -1
  193. package/fesm2022/ngwr-segmented-testing.mjs.map +1 -1
  194. package/fesm2022/ngwr-segmented.mjs +29 -6
  195. package/fesm2022/ngwr-segmented.mjs.map +1 -1
  196. package/fesm2022/ngwr-select.mjs +159 -34
  197. package/fesm2022/ngwr-select.mjs.map +1 -1
  198. package/fesm2022/ngwr-shiny-text.mjs +11 -9
  199. package/fesm2022/ngwr-shiny-text.mjs.map +1 -1
  200. package/fesm2022/ngwr-sidebar.mjs +31 -16
  201. package/fesm2022/ngwr-sidebar.mjs.map +1 -1
  202. package/fesm2022/ngwr-skeleton.mjs +3 -3
  203. package/fesm2022/ngwr-slider.mjs +100 -9
  204. package/fesm2022/ngwr-slider.mjs.map +1 -1
  205. package/fesm2022/ngwr-sparkline.mjs +3 -3
  206. package/fesm2022/ngwr-speed-dial-testing.mjs +15 -13
  207. package/fesm2022/ngwr-speed-dial-testing.mjs.map +1 -1
  208. package/fesm2022/ngwr-speed-dial.mjs +27 -12
  209. package/fesm2022/ngwr-speed-dial.mjs.map +1 -1
  210. package/fesm2022/ngwr-spinner.mjs +3 -3
  211. package/fesm2022/ngwr-splash-cursor.mjs +3 -3
  212. package/fesm2022/ngwr-split-text.mjs +17 -5
  213. package/fesm2022/ngwr-split-text.mjs.map +1 -1
  214. package/fesm2022/ngwr-splitter.mjs +3 -3
  215. package/fesm2022/ngwr-spotlight-card.mjs +7 -7
  216. package/fesm2022/ngwr-spotlight-card.mjs.map +1 -1
  217. package/fesm2022/ngwr-squircle.mjs +6 -6
  218. package/fesm2022/ngwr-star-border.mjs +4 -4
  219. package/fesm2022/ngwr-star-border.mjs.map +1 -1
  220. package/fesm2022/ngwr-statistic.mjs +9 -9
  221. package/fesm2022/ngwr-stepper-testing.mjs +8 -8
  222. package/fesm2022/ngwr-stepper-testing.mjs.map +1 -1
  223. package/fesm2022/ngwr-stepper.mjs +33 -8
  224. package/fesm2022/ngwr-stepper.mjs.map +1 -1
  225. package/fesm2022/ngwr-storage.mjs +17 -5
  226. package/fesm2022/ngwr-storage.mjs.map +1 -1
  227. package/fesm2022/ngwr-switch.mjs +3 -3
  228. package/fesm2022/ngwr-table.mjs +99 -39
  229. package/fesm2022/ngwr-table.mjs.map +1 -1
  230. package/fesm2022/ngwr-tabs-testing.mjs +11 -10
  231. package/fesm2022/ngwr-tabs-testing.mjs.map +1 -1
  232. package/fesm2022/ngwr-tabs.mjs +36 -10
  233. package/fesm2022/ngwr-tabs.mjs.map +1 -1
  234. package/fesm2022/ngwr-textarea.mjs +3 -3
  235. package/fesm2022/ngwr-theme.mjs +181 -4
  236. package/fesm2022/ngwr-theme.mjs.map +1 -1
  237. package/fesm2022/ngwr-tilt-card.mjs +7 -7
  238. package/fesm2022/ngwr-tilt-card.mjs.map +1 -1
  239. package/fesm2022/ngwr-timeline.mjs +6 -6
  240. package/fesm2022/ngwr-toast.mjs +9 -9
  241. package/fesm2022/ngwr-toolbar.mjs +3 -3
  242. package/fesm2022/ngwr-tour.mjs +34 -10
  243. package/fesm2022/ngwr-tour.mjs.map +1 -1
  244. package/fesm2022/ngwr-transfer.mjs +3 -3
  245. package/fesm2022/ngwr-tree.mjs +28 -10
  246. package/fesm2022/ngwr-tree.mjs.map +1 -1
  247. package/fesm2022/ngwr-typewriter-testing.mjs +15 -1
  248. package/fesm2022/ngwr-typewriter-testing.mjs.map +1 -1
  249. package/fesm2022/ngwr-typewriter.mjs +13 -5
  250. package/fesm2022/ngwr-typewriter.mjs.map +1 -1
  251. package/fesm2022/ngwr-typography.mjs +3 -3
  252. package/fesm2022/ngwr-utils.mjs +5 -2
  253. package/fesm2022/ngwr-utils.mjs.map +1 -1
  254. package/fesm2022/ngwr-version.mjs +1 -1
  255. package/fesm2022/ngwr-version.mjs.map +1 -1
  256. package/fesm2022/ngwr-virtual-scroll.mjs +4 -4
  257. package/fesm2022/ngwr-virtual-scroll.mjs.map +1 -1
  258. package/fesm2022/ngwr-waves.mjs +4 -4
  259. package/fesm2022/ngwr-waves.mjs.map +1 -1
  260. package/fesm2022/ngwr-window.mjs +94 -24
  261. package/fesm2022/ngwr-window.mjs.map +1 -1
  262. package/file-upload/styles/_index.scss +2 -2
  263. package/glitch-text/styles/_index.scss +27 -12
  264. package/i18n/en.json +56 -6
  265. package/i18n/ru.json +56 -6
  266. package/image-cropper/styles/_index.scss +19 -0
  267. package/input/styles/_index.scss +2 -2
  268. package/input-number/styles/_index.scss +2 -2
  269. package/input-otp/styles/_index.scss +9 -2
  270. package/knob/styles/_index.scss +1 -1
  271. package/lightbox/styles/_index.scss +16 -2
  272. package/line-chart/styles/_index.scss +28 -14
  273. package/list/styles/_index.scss +1 -1
  274. package/llms-full.txt +18 -23
  275. package/llms.txt +22 -6
  276. package/markdown/styles/_index.scss +3 -3
  277. package/mcp/api.js +6 -4
  278. package/mcp/catalog.js +40 -3
  279. package/mcp/providers.js +16 -3
  280. package/mcp/tools.js +21 -1
  281. package/meter-group/styles/_index.scss +1 -1
  282. package/overlay/styles/_index.scss +33 -1
  283. package/package.json +17 -12
  284. package/pagination/styles/_index.scss +23 -1
  285. package/popover/styles/_index.scss +16 -7
  286. package/progress/styles/_index.scss +1 -1
  287. package/radio/styles/_index.scss +2 -2
  288. package/rating/styles/_index.scss +1 -1
  289. package/schematics/collection.json +1 -1
  290. package/schematics/migrations/v12/index.js +65 -0
  291. package/schematics/migrations/v7/index.js +12 -1
  292. package/schematics/migrations/v8/index.js +10 -1
  293. package/schematics/migrations.json +5 -0
  294. package/schematics/ng-add/index.js +8 -3
  295. package/schematics/provider/index.js +80 -13
  296. package/schematics/use/index.js +9 -129
  297. package/schematics/use/rule.js +206 -0
  298. package/schematics/use/symbol-map.json +4 -4
  299. package/segmented/styles/_index.scss +14 -3
  300. package/select/styles/_index.scss +14 -2
  301. package/sidebar/styles/_index.scss +12 -10
  302. package/skills/ngwr/SKILL.md +7 -5
  303. package/skills/ngwr/references/catalog.md +9 -9
  304. package/skills/ngwr/references/setup.md +10 -5
  305. package/slider/styles/_index.scss +1 -1
  306. package/speed-dial/styles/_index.scss +1 -1
  307. package/stepper/styles/_index.scss +12 -3
  308. package/switch/styles/_index.scss +2 -2
  309. package/table/styles/_index.scss +61 -12
  310. package/tabs/styles/_index.scss +1 -1
  311. package/textarea/styles/_index.scss +1 -1
  312. package/theme/styles/_colors.scss +142 -56
  313. package/theme/styles/_dark.scss +46 -3
  314. package/theme/styles/_focus.scss +28 -5
  315. package/theme/styles/_mixins.scss +1 -1
  316. package/theme/styles/_variables.scss +67 -0
  317. package/transfer/styles/_index.scss +26 -3
  318. package/tree/styles/_index.scss +29 -6
  319. package/types/ngwr-bar-chart-testing.d.ts +9 -1
  320. package/types/ngwr-blur-text.d.ts +8 -4
  321. package/types/ngwr-breadcrumbs.d.ts +17 -10
  322. package/types/ngwr-calendar-testing.d.ts +1 -1
  323. package/types/ngwr-calendar.d.ts +66 -0
  324. package/types/ngwr-carousel.d.ts +85 -6
  325. package/types/ngwr-cascader.d.ts +17 -0
  326. package/types/ngwr-click-spark.d.ts +4 -0
  327. package/types/ngwr-color-picker-testing.d.ts +8 -0
  328. package/types/ngwr-color-picker.d.ts +21 -1
  329. package/types/ngwr-confetti.d.ts +8 -0
  330. package/types/ngwr-config.d.ts +10 -1
  331. package/types/ngwr-context-menu-testing.d.ts +24 -11
  332. package/types/ngwr-context-menu.d.ts +56 -0
  333. package/types/ngwr-counter.d.ts +1 -0
  334. package/types/{ngwr-date-adapter-fns.d.ts → ngwr-date-adapters-fns.d.ts} +33 -6
  335. package/types/{ngwr-date-adapter-luxon.d.ts → ngwr-date-adapters-luxon.d.ts} +1 -1
  336. package/types/ngwr-date-picker-testing.d.ts +11 -6
  337. package/types/ngwr-date-picker.d.ts +8 -4
  338. package/types/{ngwr-date-adapter.d.ts → ngwr-date.d.ts} +24 -5
  339. package/types/ngwr-dialog.d.ts +38 -1
  340. package/types/ngwr-divider.d.ts +25 -0
  341. package/types/ngwr-donut-chart-testing.d.ts +7 -3
  342. package/types/ngwr-donut-chart.d.ts +3 -3
  343. package/types/ngwr-drag-drop.d.ts +56 -2
  344. package/types/ngwr-drawer.d.ts +56 -5
  345. package/types/ngwr-event-calendar.d.ts +8 -2
  346. package/types/ngwr-falling-text-testing.d.ts +5 -3
  347. package/types/ngwr-falling-text.d.ts +1 -1
  348. package/types/ngwr-form.d.ts +12 -2
  349. package/types/ngwr-glitch-text-testing.d.ts +37 -8
  350. package/types/ngwr-gradient-text-testing.d.ts +16 -3
  351. package/types/ngwr-i18n.d.ts +13 -4
  352. package/types/ngwr-image-cropper-testing.d.ts +49 -10
  353. package/types/ngwr-image-cropper.d.ts +70 -5
  354. package/types/ngwr-input-number-testing.d.ts +15 -10
  355. package/types/ngwr-input-number.d.ts +11 -4
  356. package/types/ngwr-input-otp-testing.d.ts +12 -6
  357. package/types/ngwr-input-otp.d.ts +15 -1
  358. package/types/ngwr-line-chart.d.ts +20 -3
  359. package/types/ngwr-markdown.d.ts +11 -0
  360. package/types/ngwr-mention.d.ts +32 -0
  361. package/types/ngwr-meter-group-testing.d.ts +12 -2
  362. package/types/ngwr-overlay.d.ts +1 -0
  363. package/types/ngwr-pagination-testing.d.ts +4 -4
  364. package/types/ngwr-pipes.d.ts +1 -1
  365. package/types/ngwr-popover-testing.d.ts +7 -2
  366. package/types/ngwr-popover.d.ts +1 -0
  367. package/types/ngwr-result.d.ts +6 -0
  368. package/types/ngwr-segmented-testing.d.ts +9 -0
  369. package/types/ngwr-segmented.d.ts +21 -1
  370. package/types/ngwr-select.d.ts +68 -6
  371. package/types/ngwr-shiny-text.d.ts +4 -2
  372. package/types/ngwr-sidebar.d.ts +14 -5
  373. package/types/ngwr-slider.d.ts +69 -1
  374. package/types/ngwr-speed-dial-testing.d.ts +15 -11
  375. package/types/ngwr-speed-dial.d.ts +22 -3
  376. package/types/ngwr-split-text.d.ts +9 -0
  377. package/types/ngwr-stepper-testing.d.ts +5 -5
  378. package/types/ngwr-stepper.d.ts +8 -0
  379. package/types/ngwr-storage.d.ts +1 -0
  380. package/types/ngwr-table.d.ts +104 -11
  381. package/types/ngwr-tabs-testing.d.ts +11 -10
  382. package/types/ngwr-tabs.d.ts +2 -0
  383. package/types/ngwr-theme.d.ts +82 -1
  384. package/types/ngwr-tour.d.ts +22 -4
  385. package/types/ngwr-tree.d.ts +5 -4
  386. package/types/ngwr-typewriter-testing.d.ts +10 -0
  387. package/types/ngwr-utils.d.ts +5 -2
  388. package/types/ngwr-version.d.ts +1 -1
  389. package/types/ngwr-window.d.ts +39 -11
  390. package/typography/styles/_index.scss +1 -1
  391. package/window/styles/_index.scss +72 -26
  392. package/fesm2022/ngwr-date-adapter-fns.mjs.map +0 -1
  393. package/fesm2022/ngwr-date-adapter-luxon.mjs.map +0 -1
  394. package/fesm2022/ngwr-date-adapter.mjs.map +0 -1
@@ -133,8 +133,18 @@ declare class WrFormField implements WrFormFieldContext {
133
133
  readonly hint: _angular_core.InputSignal<string>;
134
134
  /** Show a `*` next to the label. @default false */
135
135
  readonly required: _angular_core.InputSignalWithTransform<boolean, any>;
136
- /** Show `(optional)` next to the label. Mutually exclusive with `required`. @default false */
136
+ /**
137
+ * Show an "optional" marker next to the label — the word comes from
138
+ * `optionalLabel`. Mutually exclusive with `required`. @default false
139
+ */
137
140
  readonly optional: _angular_core.InputSignalWithTransform<boolean, any>;
141
+ /**
142
+ * Word inside the optional marker's parentheses. Falls back to
143
+ * `form.optional`, then `'optional'`. The parentheses are the template's, so
144
+ * no locale has to repeat punctuation.
145
+ */
146
+ readonly optionalLabel: _angular_core.InputSignal<string | null>;
147
+ protected readonly resolvedOptional: _angular_core.Signal<string>;
138
148
  /**
139
149
  * Force a specific id on the label's `for` attribute. Auto-generated
140
150
  * otherwise, and adopted by the projected `wrInput` unless that element
@@ -201,7 +211,7 @@ declare class WrFormField implements WrFormFieldContext {
201
211
  private resolve;
202
212
  protected readonly classes: _angular_core.Signal<string>;
203
213
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrFormField, never>;
204
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrFormField, "wr-form-field", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "optional": { "alias": "optional"; "required": false; "isSignal": true; }; "controlId": { "alias": "controlId"; "required": false; "isSignal": true; }; "autoErrors": { "alias": "autoErrors"; "required": false; "isSignal": true; }; }, {}, ["ngControl", "projectedErrors"], ["*", "wr-form-error"], true, never>;
214
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrFormField, "wr-form-field", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "optional": { "alias": "optional"; "required": false; "isSignal": true; }; "optionalLabel": { "alias": "optionalLabel"; "required": false; "isSignal": true; }; "controlId": { "alias": "controlId"; "required": false; "isSignal": true; }; "autoErrors": { "alias": "autoErrors"; "required": false; "isSignal": true; }; }, {}, ["ngControl", "projectedErrors"], ["*", "wr-form-error"], true, never>;
205
215
  }
206
216
 
207
217
  /**
@@ -45,10 +45,15 @@ interface WrGlitchTextColourSplit {
45
45
  *
46
46
  * **The one thing worth testing here is the pairing.** The two torn clones are
47
47
  * `::before` / `::after` pseudo-elements whose glyphs come from `content:
48
- * attr(data-text)`, so the string has to be in the host's text node AND in the host's
49
- * `data-text` attribute. Drop either binding and the visible text stays flawless while
50
- * the effect disappears — no error, no missing element, nothing else in the DOM
51
- * changes. {@link isCloneTextInSync} is that assertion in one call.
48
+ * attr(data-text)`, so the string has to be in `__label`'s text node AND in the
49
+ * `data-text` attribute on `__clones`. Drop either binding and the visible text stays
50
+ * flawless while the effect disappears — no error, no missing element, nothing else in
51
+ * the DOM changes. {@link isCloneTextInSync} is that assertion in one call.
52
+ *
53
+ * **Why they are two elements**, which is also why `data-text` is not on the host:
54
+ * generated content is exposed to the accessibility tree, so pseudos on the host made
55
+ * the string announce three times. `__clones` carries the `aria-hidden`;
56
+ * {@link isCloneLayerHidden} is the assertion that keeps it there.
52
57
  *
53
58
  * **Everything else the harness reads is an inline custom property**, because that is
54
59
  * everything the component writes: the two clone durations, the two colour-split
@@ -85,18 +90,22 @@ interface WrGlitchTextColourSplit {
85
90
  */
86
91
  declare class WrGlitchTextHarness extends ComponentHarness {
87
92
  static hostSelector: string;
93
+ /** The readable copy of the string — the only part of the component in the a11y tree. */
94
+ private readonly label;
95
+ /** The `aria-hidden` layer the two pseudo-clones hang off. */
96
+ private readonly clones;
88
97
  /** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */
89
98
  static with(options?: WrGlitchTextHarnessFilters): HarnessPredicate<WrGlitchTextHarness>;
90
99
  /**
91
100
  * The rendered text, trimmed.
92
101
  *
93
102
  * The half a sighted user reads, and the half every other check would notice
94
- * breaking. The component interpolates the input straight onto the host, so there is
95
- * no inner element to query.
103
+ * breaking. Read off `__label`, which is the whole of the component's accessible
104
+ * content — the clone layer beside it is `aria-hidden` and empty in the DOM.
96
105
  */
97
106
  getText(): Promise<string>;
98
107
  /**
99
- * The string the two clone layers draw from — the host's `data-text`.
108
+ * The string the two clone layers draw from — `data-text` on `__clones`.
100
109
  *
101
110
  * The half nothing else notices. `content: attr(data-text)` is how both pseudo-clones
102
111
  * get their glyphs, so this attribute IS the effect. `null` means the mirror is gone
@@ -108,12 +117,23 @@ declare class WrGlitchTextHarness extends ComponentHarness {
108
117
  *
109
118
  * The component's defining silent failure, as a single assertion — two separate reads
110
119
  * are two things a spec can forget to write together. Compared raw on both sides,
111
- * with no trimming: the template is the bare interpolation, so the text node and the
120
+ * with no trimming: `__label` holds the bare interpolation, so its text node and the
112
121
  * attribute are byte-identical or the mirror is broken. An empty `text` is legal and
113
122
  * counts as in sync — `data-text=""` is a mirror of nothing, not a missing binding,
114
123
  * which is why {@link getCloneText} reports the absent case as `null` instead.
115
124
  */
116
125
  isCloneTextInSync(): Promise<boolean>;
126
+ /**
127
+ * Whether the clone layer is still hidden from assistive technology.
128
+ *
129
+ * The reason the component is two elements rather than one. `content: attr(data-text)`
130
+ * is exposed to the accessibility tree, so with the pseudos on the host the string was
131
+ * announced three times and a wrapping heading or link computed its name as
132
+ * "404 404 404". Nothing visual changes if the `aria-hidden` is dropped, and neither
133
+ * a11y gate in this repo can see it: `check:a11y` reads prerendered HTML with no
134
+ * stylesheets, and axe has no rule for duplicated generated content.
135
+ */
136
+ isCloneLayerHidden(): Promise<boolean>;
117
137
  /**
118
138
  * Whether the effect idles until the pointer arrives (`enableOnHover`).
119
139
  *
@@ -164,6 +184,15 @@ declare class WrGlitchTextHarness extends ComponentHarness {
164
184
  * the whole reason this reports the absent case as `null` instead of as a colour.
165
185
  */
166
186
  getSliceBackground(): Promise<string | null>;
187
+ /**
188
+ * One custom property off the host's `style` ATTRIBUTE.
189
+ *
190
+ * Not `getCssValue()`, which is `getComputedStyle`: with the entry point's own
191
+ * stylesheet loaded that resolves the sheet's declaration, so the method
192
+ * answers plausibly at exactly the moment the host binding — the thing under
193
+ * test — is what broke. The attribute holds only what the component wrote.
194
+ */
195
+ private inlineVar;
167
196
  /** One of the host's inline duration properties, as a number of seconds. */
168
197
  private seconds;
169
198
  }
@@ -38,6 +38,15 @@ interface WrGradientTextHarnessFilters extends BaseHarnessFilters {
38
38
  * included, because the duplicate is the thing worth asserting and stripping it would
39
39
  * hide the day it goes missing.
40
40
  *
41
+ * **The three custom properties are read off the `style` ATTRIBUTE, not through
42
+ * `getCssValue()`, and that is not a jsdom concession.** `.wr-gradient-text` declares
43
+ * its own `--wr-gradient-text-image`, `-size` and `-duration`, spelling out the same
44
+ * defaults the component computes — the three built-in stops with their wrap stop,
45
+ * `300% 100%`, `8s`. So with the stylesheet loaded a computed read answers with a
46
+ * perfectly healthy-looking value at exactly the moment the host binding is what broke,
47
+ * and every throw below goes unreachable. What the component wrote is the only value
48
+ * nothing else can forge.
49
+ *
41
50
  * **Direction is two facts, not one.** The modifier class says which way the gradient
42
51
  * travels and {@link getBackgroundSize} says which axis it was stretched along, and they
43
52
  * are computed separately: a direction change that forgets the size leaves every class
@@ -111,8 +120,9 @@ declare class WrGradientTextHarness extends ComponentHarness {
111
120
  * shows up here as four entries rather than one.
112
121
  *
113
122
  * Throws rather than guessing when the property holds something that is not a
114
- * `linear-gradient()` — an empty read means the host binding is gone, and a list of
115
- * fragments parsed out of the wreckage would look like a colour set.
123
+ * `linear-gradient()`, because a list of fragments parsed out of the wreckage would
124
+ * look like a colour set. A host that publishes no gradient at all throws one step
125
+ * earlier, from {@link getGradient}.
116
126
  */
117
127
  getColors(): Promise<string[]>;
118
128
  /**
@@ -130,7 +140,8 @@ declare class WrGradientTextHarness extends ComponentHarness {
130
140
  *
131
141
  * Proves the input reaches CSS at all, `numAttr` coercion included — a string attribute
132
142
  * arrives as a number and garbage falls back to the documented default. Throws when the
133
- * property holds no number, which is the only way the read can fail.
143
+ * property holds something that is not a number of seconds; a host that publishes no
144
+ * duration at all throws from the read itself.
134
145
  */
135
146
  getAnimationDurationSeconds(): Promise<number>;
136
147
  /**
@@ -167,6 +178,8 @@ declare class WrGradientTextHarness extends ComponentHarness {
167
178
  * arriving, which is the half that can go wrong in TypeScript.
168
179
  */
169
180
  pausesOnHover(): Promise<boolean>;
181
+ /** One of the host's own custom properties. See the class note on why this is not `getCssValue()`. */
182
+ private published;
170
183
  }
171
184
 
172
185
  export { WrGradientTextHarness };
@@ -380,11 +380,20 @@ declare function provideWrI18nHttpLoader(config: WrI18nHttpLoaderConfig): Provid
380
380
  */
381
381
  declare function useI18nText(binding: Signal<string | null | undefined>, key: string, fallback: string): Signal<string>;
382
382
  /**
383
- * Like {@link useI18nText} but takes a literal value (not a Signal) — for
384
- * computed `aria-label`s that already mix a static piece with a dynamic
385
- * value. Returns the resolved string once, at injection time.
383
+ * {@link useI18nText} without a binding to forward — for a built-in string the
384
+ * component exposes no override input for. Same reactivity, same fallback
385
+ * rules; the only difference is the missing first argument.
386
+ *
387
+ * It used to return a plain `string`, resolved once at injection time, and
388
+ * that was wrong in the ordinary case rather than an edge one: `WrI18n` writes
389
+ * every loader-backed catalog from `firstValueFrom(...).then(...)`, so even a
390
+ * static loader serving an object literal lands a microtask AFTER the first
391
+ * change-detection pass. Every component built in that pass read an empty
392
+ * catalog and froze its English fallback for the life of the app — in one
393
+ * `<wr-date-picker>` the field said "Открыть календарь" and the calendar
394
+ * button beside it "Open calendar", off the same key.
386
395
  */
387
- declare function readI18nText(key: string, fallback: string): string;
396
+ declare function readI18nText(key: string, fallback: string): Signal<string>;
388
397
  /**
389
398
  * Build a per-call formatter for parametrized labels (e.g. ARIA labels
390
399
  * that interpolate a per-row value: `"Remove {{label}}"`). Returns a
@@ -1,4 +1,4 @@
1
- import { BaseHarnessFilters, ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';
1
+ import { BaseHarnessFilters, TestKey, ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';
2
2
  import { WrCropHandle } from 'ngwr/image-cropper';
3
3
 
4
4
  /**
@@ -25,6 +25,14 @@ interface WrImageCropperHarnessFilters extends BaseHarnessFilters {
25
25
  * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
26
26
  */
27
27
 
28
+ declare const ARROWS: {
29
+ readonly left: TestKey.LEFT_ARROW;
30
+ readonly right: TestKey.RIGHT_ARROW;
31
+ readonly up: TestKey.UP_ARROW;
32
+ readonly down: TestKey.DOWN_ARROW;
33
+ };
34
+ /** The four directions the crop window's keyboard model understands. */
35
+ type WrCropArrow = keyof typeof ARROWS;
28
36
  /** Where the crop window sits over the DISPLAYED image, in CSS pixels. */
29
37
  interface WrCropWindowBox {
30
38
  readonly x: number;
@@ -41,13 +49,16 @@ interface WrCropWindowBox {
41
49
  * `naturalWidth`, converts between display and source pixels, and moves the crop
42
50
  * window with pointer deltas. jsdom measures nothing — every rect is 0×0 and
43
51
  * `naturalWidth` is 0 — so an image never "loads", the crop UI never renders, and a
44
- * synthetic drag divides by zero. There is deliberately no `moveCrop()` or
45
- * `resizeCrop()`: either would write `NaN` and report success.
52
+ * synthetic drag divides by zero. There is deliberately no drag method: it would
53
+ * write `NaN` and report success.
46
54
  *
47
55
  * What a spec CAN do is give the image a box and a natural size itself, then call
48
56
  * {@link dispatchImageLoad} — the two numbers `onImageLoad` reads are the whole
49
57
  * stub, and from there {@link getCropBox} and {@link getHandles} are real answers,
50
- * because the component writes the crop window's geometry as inline pixels.
58
+ * because the component writes the crop window's geometry as inline pixels. The
59
+ * KEYBOARD path needs the same stub to get the crop UI up, but nothing beyond it:
60
+ * its step is a constant rather than a pointer delta, so {@link pressArrow} lands
61
+ * on a number a spec can name.
51
62
  *
52
63
  * ```ts
53
64
  * // In your spec, before dispatching the load:
@@ -57,11 +68,13 @@ interface WrCropWindowBox {
57
68
  * Object.defineProperty(img, 'naturalHeight', { value: 800 });
58
69
  * ```
59
70
  *
60
- * **There is also nothing to click.** The cropper renders no buttons: a consumer
61
- * takes the result by calling `crop()` on the component through a `viewChild`, and
62
- * reads `cropRect()` the same way. Those are component API rather than DOM, so they
63
- * are outside what a harness can reach at all — which is worth knowing rather than
64
- * discovering.
71
+ * **There is nothing to click.** The cropper renders no buttons: the result
72
+ * arrives on the `(cropped)` output, which emits a `Blob` after each drag end or
73
+ * each run of arrow keys, and a consumer who wants a one-off read calls `toBlob()` /
74
+ * `toDataUrl()` — or `cropRect()` for the geometry — on the component through a
75
+ * `viewChild`. An output and three instance members: component API rather than DOM,
76
+ * so all of it is outside what a harness can reach at all, which is worth knowing
77
+ * rather than discovering.
65
78
  *
66
79
  * @example
67
80
  * ```ts
@@ -127,8 +140,34 @@ declare class WrImageCropperHarness extends ComponentHarness {
127
140
  getHandles(): Promise<WrCropHandle[]>;
128
141
  /** Whether the dimming backdrop with the cut-out is drawn. */
129
142
  hasBackdrop(): Promise<boolean>;
143
+ /**
144
+ * Press an arrow key on the crop window — one display pixel, or ten with
145
+ * `shift`; `alt` resizes from the east / south edge instead of moving.
146
+ *
147
+ * Sent to the crop window, where the component listens, so it does not depend on
148
+ * jsdom having managed to focus anything. `sendKeys` fires keyup as well as
149
+ * keydown, which is what makes `(cropped)` emit — the component treats a run of
150
+ * arrows as one gesture, the way a drag is one.
151
+ */
152
+ pressArrow(arrow: WrCropArrow, modifiers?: {
153
+ alt?: boolean;
154
+ shift?: boolean;
155
+ }): Promise<void>;
156
+ /** The crop window's accessible name. Comes from the catalog. */
157
+ getCropWindowLabel(): Promise<string | null>;
158
+ /**
159
+ * The last thing the live region announced — the crop rect in SOURCE pixels,
160
+ * as `x, y, width × height`.
161
+ *
162
+ * Empty until a key has moved the crop: a pointer drag deliberately says nothing
163
+ * (it would flood the region and the sighted user can see it), and the initial
164
+ * crop is not news. Two questions, not one — {@link getCropBox} reads the window's
165
+ * DISPLAY geometry, and a component that moved the box without announcing it
166
+ * would still pass that one.
167
+ */
168
+ getAnnouncement(): Promise<string>;
130
169
  private requireReady;
131
170
  }
132
171
 
133
172
  export { WrImageCropperHarness };
134
- export type { WrImageCropperHarnessFilters };
173
+ export type { WrCropArrow, WrCropWindowBox, WrImageCropperHarnessFilters };
@@ -30,8 +30,12 @@ interface RectPx {
30
30
  * the crop window or any of its eight handles. Optionally lock the crop
31
31
  * to a fixed `[aspectRatio]`.
32
32
  *
33
- * `(cropped)` fires after each drag end with a freshly-rendered `Blob`
34
- * of the cropped region. For one-off reads use `toBlob()` / `toDataUrl()`.
33
+ * The crop window is also the one tab stop: arrow keys move it, Alt with an
34
+ * arrow key resizes it, and Shift makes either step ten pixels instead of one.
35
+ *
36
+ * `(cropped)` fires after each drag end — or each run of arrow keys — with a
37
+ * freshly-rendered `Blob` of the cropped region. For one-off reads use
38
+ * `toBlob()` / `toDataUrl()`.
35
39
  *
36
40
  * @example
37
41
  * ```html
@@ -62,6 +66,15 @@ declare class WrImageCropper {
62
66
  protected readonly imgEl: _angular_core.Signal<ElementRef<HTMLImageElement>>;
63
67
  /** Resolved object URL for `src` (so File / Blob render in `<img>`). */
64
68
  protected readonly emptyText: _angular_core.Signal<string>;
69
+ /** Accessible name of the crop window — the component's only tab stop. */
70
+ protected readonly resolvedWindowLabel: _angular_core.Signal<string>;
71
+ /** The key model, referenced by the window's `aria-describedby`. */
72
+ protected readonly resolvedKeyHelp: _angular_core.Signal<string>;
73
+ /** Id linking the crop window to the help text. Random rather than counted:
74
+ * the crop UI only exists after a real image load, so it never prerenders. */
75
+ protected readonly helpId: string;
76
+ /** Live-region text — written by the keyboard path only (see `onWindowKeydown`). */
77
+ protected readonly announcement: _angular_core.WritableSignal<string>;
65
78
  protected readonly objectUrl: _angular_core.WritableSignal<string | null>;
66
79
  /** Previous object URL we created — kept off-signal so the resolve
67
80
  * effect doesn't depend on its own writes (which would loop). */
@@ -78,6 +91,8 @@ declare class WrImageCropper {
78
91
  }>;
79
92
  /** Crop rect in display coordinates. */
80
93
  protected readonly cropDisplay: _angular_core.WritableSignal<RectPx>;
94
+ /** Watches the rendered image box — see `watchResize`. */
95
+ private resizeObserver;
81
96
  /** Currently active drag handle. */
82
97
  private active;
83
98
  private startPointer;
@@ -91,18 +106,68 @@ declare class WrImageCropper {
91
106
  *
92
107
  * `display` is the field that gates everything downstream — the crop UI renders on
93
108
  * `display().w > 0` and `cropRect` returns zeros without it — so it is the only one
94
- * a test can observe. The other two are reset for coherence: anything that learns to
95
- * set `display` from elsewhere (a resize observer is the obvious candidate for this
96
- * component) would otherwise resurrect a crop measured against the previous image.
109
+ * a test can observe. The other two are reset for coherence: the resize observer
110
+ * below also writes `display`, and left alone they would resurrect a crop measured
111
+ * against the previous image (which is why `onResize` refuses to run on a zeroed
112
+ * `display` — see there).
97
113
  */
98
114
  private resetGeometry;
99
115
  protected onImageLoad(): void;
116
+ /**
117
+ * Keep `display` on the box the image is actually rendered at.
118
+ *
119
+ * The stylesheet sizes the image responsively — `max-width: 100%`,
120
+ * `max-height: 70dvh`, `height: auto` — so the single measurement taken in the
121
+ * `(load)` handler stops being true as soon as the container or the viewport
122
+ * changes. Everything the user sees and touches is in DISPLAY pixels: the crop
123
+ * window's inline `left` / `top` / `width` / `height`, the backdrop cut-out, and
124
+ * the bounds `applyMove` / `applyResize` clamp against. Measured once, a narrowed
125
+ * window leaves the crop painted past the edge of the image and draggable off it.
126
+ *
127
+ * Re-observed per load rather than once, because a new `src` may mount a new
128
+ * `<img>`; the old observation would then be on a detached element.
129
+ */
130
+ private watchResize;
131
+ /**
132
+ * Rescale the crop by however much the image did, so the user keeps the region
133
+ * they picked instead of having it re-centred: `cropRect()` — the source-pixel
134
+ * value a consumer acts on — comes out the same across the resize.
135
+ */
136
+ private onResize;
100
137
  /** Compute a sensible initial crop — centered, respecting aspectRatio. */
101
138
  private initialCrop;
102
139
  protected readonly handles: readonly WrCropHandle[];
103
140
  protected onPointerDown(handle: WrCropHandle, event: PointerEvent): void;
104
141
  protected onPointerMove(event: PointerEvent): void;
105
142
  protected onPointerUp(event: PointerEvent): void;
143
+ /** Whether a key has moved the crop since the last `keyup`. */
144
+ private keyboardDirty;
145
+ /**
146
+ * The component's only keyboard path. Arrow keys move the crop window; Alt
147
+ * with an arrow key resizes it from the east / south edge; Shift makes either
148
+ * one ten display pixels instead of one — the coarse modifier `wr-slider`,
149
+ * `wr-knob` and `wr-splitter` all use, which is why Alt and not Shift carries
150
+ * the mode switch here.
151
+ *
152
+ * Nothing mirrors under `dir="rtl"`: the image is not flipped and the window
153
+ * is placed with a physical `left`, so ArrowLeft moves the crop visually left
154
+ * in both directions.
155
+ *
156
+ * Both branches go through `applyMove` / `applyResize`, so the `aspectRatio`
157
+ * lock, the `minWidth` / `minHeight` floors and the canvas bounds hold for a
158
+ * keystroke exactly as they do for a drag. Those two measure from `startRect`
159
+ * rather than from the live rect, so it is re-seeded per keystroke — a 1px
160
+ * delta against the rect from the first press would make a held arrow stall
161
+ * after one pixel instead of accumulating.
162
+ */
163
+ protected onWindowKeydown(event: KeyboardEvent): void;
164
+ /**
165
+ * Emit once per gesture, not once per keystroke. A held arrow repeats its
166
+ * keydown many times a second and each `emitCropped` renders a canvas and
167
+ * encodes a Blob; `keyup` fires once when the run ends, which is the keyboard's
168
+ * equivalent of the `pointerup` the drag path emits on.
169
+ */
170
+ protected onWindowKeyup(): void;
106
171
  private applyMove;
107
172
  private applyResize;
108
173
  /** Render the current crop as a Blob. */
@@ -173,13 +173,17 @@ declare class WrInputNumberHarness extends ComponentHarness {
173
173
  /** The field's placeholder. */
174
174
  getPlaceholder(): Promise<string>;
175
175
  /**
176
- * The field's accessible name, or `null` when it has none of its own.
176
+ * The field's `aria-label`, or `null` when it carries none.
177
177
  *
178
178
  * Read from the native input, not from the host: an `aria-label` on a component
179
179
  * element does not reach the control inside it, which is why the component
180
- * takes an `ariaLabel` input and forwards it here (falling back to the
181
- * placeholder). Inside a `<wr-form-field>` the name comes from the label's
182
- * `for`, and `null` here is then correct rather than a missing name.
180
+ * takes an `ariaLabel` input and forwards it here.
181
+ *
182
+ * NOT the accessible name — `null` is the usual answer and usually correct.
183
+ * Nothing is forwarded unless `[ariaLabel]` is bound: inside a
184
+ * `<wr-form-field>` the name comes from the label's `for`, and standalone it
185
+ * comes from the `placeholder` (see {@link getPlaceholder}), neither of which
186
+ * is an attribute on this element.
183
187
  */
184
188
  getAriaLabel(): Promise<string | null>;
185
189
  /**
@@ -212,12 +216,13 @@ declare class WrInputNumberHarness extends ComponentHarness {
212
216
  /**
213
217
  * One of the two stepper buttons, BY POSITION — ▲ first, ▼ second.
214
218
  *
215
- * Not by `aria-label`: those strings ("Increment" / "Decrement") are still
216
- * hard-coded English, so keying on them would make this harness the thing that
217
- * breaks when they move into the i18n catalog — the same call
218
- * `WrTimePanelHarness` makes about its own columns. Order is the layout
219
- * contract, and the spec pins it by asserting which way each button moves the
220
- * value.
219
+ * Not by `aria-label`: those strings resolve through the i18n catalog
220
+ * (`inputNumber.increment` / `.decrement`) and an `[incrementLabel]` /
221
+ * `[decrementLabel]` binding overrides them, so keying on them would make this
222
+ * harness answer in whatever locale the app under test is configured for — the
223
+ * same call `WrTimePanelHarness` makes about its own columns. Order is the
224
+ * layout contract, and the spec pins it by asserting which way each button
225
+ * moves the value.
221
226
  */
222
227
  private stepButton;
223
228
  }
@@ -14,7 +14,7 @@ import { WrInputSize } from 'ngwr/input';
14
14
  * re-formats with grouping + fixed decimals on blur.
15
15
  *
16
16
  * Locale comes from Angular's `LOCALE_ID` — input-number intentionally does
17
- * NOT depend on `ngwr/date-adapter` so it can be used in date-free apps.
17
+ * NOT depend on `ngwr/date` so it can be used in date-free apps.
18
18
  *
19
19
  * @example
20
20
  * ```html
@@ -73,9 +73,16 @@ declare class WrInputNumber implements FormValueControl<number | null> {
73
73
  /** Placeholder shown when the input is empty. */
74
74
  readonly placeholder: _angular_core.InputSignal<string>;
75
75
  /**
76
- * Accessible name for the field. Falls back to the placeholder — inside a
77
- * `<wr-form-field>` the projected `wrInput` picks up the label's id and needs
78
- * neither, but standalone the text field has no name at all.
76
+ * Accessible name for the field. Unset, the field is named by whatever labels
77
+ * it — there is deliberately no fallback here.
78
+ *
79
+ * It used to mirror the `placeholder`, and an `aria-label` OUTRANKS a
80
+ * `<label>` in the accname order: inside a `<wr-form-field label="Quantity">`
81
+ * the very input that adopts the field's id announced the placeholder ("0")
82
+ * instead, and a placeholder disappears as soon as the user types. Standalone
83
+ * nothing was lost by dropping it — an input with no other name already falls
84
+ * back to its own `placeholder` attribute, which is the name axe's `label`
85
+ * rule accepts too.
79
86
  */
80
87
  readonly ariaLabel: _angular_core.InputSignal<string | null>;
81
88
  protected readonly resolvedAriaLabel: _angular_core.Signal<string | null>;
@@ -54,11 +54,11 @@ interface WrInputOtpHarnessFilters extends BaseHarnessFilters {
54
54
  * single character.
55
55
  *
56
56
  * A box is more than the string it shows: it carries its own accessible name
57
- * (`Digit 3`), its own emptiness, its own masking, and it is the thing that
58
- * either has focus or does not. The root harness answers the control's
59
- * questions (the assembled code, which index is focused); this one answers the
60
- * box's, so a spec can hold on to "the box that has focus" instead of zipping
61
- * four parallel arrays by index.
57
+ * (`Digit 3` on a numeric strip, `Character 3` on the others), its own
58
+ * emptiness, its own masking, and it is the thing that either has focus or does
59
+ * not. The root harness answers the control's questions (the assembled code,
60
+ * which index is focused); this one answers the box's, so a spec can hold on to
61
+ * "the box that has focus" instead of zipping four parallel arrays by index.
62
62
  *
63
63
  * @example
64
64
  * ```ts
@@ -93,11 +93,17 @@ declare class WrInputOtpBoxHarness extends ComponentHarness {
93
93
  /** Whether the box is still waiting for a character. */
94
94
  isEmpty(): Promise<boolean>;
95
95
  /**
96
- * The box's accessible name — `Digit 1`, `Digit 2`, …
96
+ * The box's accessible name — `Digit 1`, `Digit 2`, … on a numeric strip.
97
97
  *
98
98
  * This is the whole of a box's identity for a screen-reader user: the boxes
99
99
  * carry no visible label and no position in an `aria-*` set, so the name is
100
100
  * how someone knows which one they are in.
101
+ *
102
+ * The word depends on `mode`, so an assertion has to follow it: the
103
+ * `alphanumeric` and `text` modes accept letters, and the component names
104
+ * their boxes `Character 1`, `Character 2`, … rather than call an `A` a digit.
105
+ * Both come from the `inputOtp.digit` / `inputOtp.character` catalog entries,
106
+ * so a localized app answers here in its own language.
101
107
  */
102
108
  getLabel(): Promise<string | null>;
103
109
  /** Whether the box hides what was typed, like a password field. */
@@ -42,6 +42,9 @@ type WrInputOtpSize = 'sm' | 'md' | 'lg';
42
42
  */
43
43
  declare class WrInputOtp implements FormValueControl<string> {
44
44
  private readonly dir;
45
+ /** Accessible name of the whole strip. Falls back to `inputOtp.label`. */
46
+ readonly ariaLabel: _angular_core.InputSignal<string | null>;
47
+ protected readonly resolvedAriaLabel: _angular_core.Signal<string>;
45
48
  /** Number of cells to render. Clamped to `[1, 20]`. @default 6 */
46
49
  readonly length: _angular_core.InputSignalWithTransform<number, unknown>;
47
50
  /** Character set per cell. @default 'numeric' */
@@ -81,6 +84,8 @@ declare class WrInputOtp implements FormValueControl<string> {
81
84
  protected readonly classes: _angular_core.Signal<string>;
82
85
  protected readonly cellType: _angular_core.Signal<"text" | "password">;
83
86
  protected readonly cellInputMode: _angular_core.Signal<"numeric" | "text">;
87
+ private readonly digitLabel;
88
+ private readonly characterLabel;
84
89
  protected readonly cellRefs: _angular_core.Signal<readonly ElementRef<HTMLInputElement>[]>;
85
90
  constructor();
86
91
  protected onInput(event: Event, index: number): void;
@@ -88,6 +93,15 @@ declare class WrInputOtp implements FormValueControl<string> {
88
93
  protected onPaste(event: ClipboardEvent): void;
89
94
  protected onBlur(): void;
90
95
  protected trackIndex(index: number): number;
96
+ /**
97
+ * A box's accessible name. It projects no text and carries no label of its own,
98
+ * so this string IS the name a screen reader reads for it.
99
+ *
100
+ * Keyed off `mode`, not fixed: `sanitiseChar` passes any letter through in
101
+ * `alphanumeric` and `text`, so the old literal announced "Digit 3" over a box
102
+ * holding `A` — wrong in a way translating it would not have fixed.
103
+ */
104
+ protected cellLabel(index: number): string;
91
105
  private update;
92
106
  private emitChange;
93
107
  private focusCell;
@@ -102,7 +116,7 @@ declare class WrInputOtp implements FormValueControl<string> {
102
116
  */
103
117
  private inlineKey;
104
118
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrInputOtp, never>;
105
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrInputOtp, "wr-input-otp", never, { "length": { "alias": "length"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "mask": { "alias": "mask"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "completed": "completed"; "touch": "touch"; }, never, never, true, never>;
119
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrInputOtp, "wr-input-otp", never, { "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "length": { "alias": "length"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "mask": { "alias": "mask"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "completed": "completed"; "touch": "touch"; }, never, never, true, never>;
106
120
  }
107
121
 
108
122
  export { WrInputOtp };
@@ -55,7 +55,7 @@ declare class WrLineChart {
55
55
  protected readonly hoveredIndex: _angular_core.WritableSignal<number | null>;
56
56
  protected readonly resolvedSeries: _angular_core.Signal<{
57
57
  label: string;
58
- data: number[];
58
+ data: (number | null)[];
59
59
  color: string;
60
60
  }[]>;
61
61
  protected readonly bounds: _angular_core.Signal<{
@@ -70,12 +70,29 @@ declare class WrLineChart {
70
70
  }[]>;
71
71
  protected readonly plotWidth: () => number;
72
72
  protected readonly plotHeight: () => number;
73
- /** Get the SVG path for a series. */
73
+ /**
74
+ * The SVG path for a series — one subpath per unbroken run, so a hole in the data
75
+ * leaves a hole in the line rather than a straight segment across it.
76
+ */
74
77
  protected pathFor(series: {
75
- data: readonly number[];
78
+ data: readonly (number | null)[];
76
79
  }): string;
77
80
  protected pointX(index: number): number;
78
81
  protected pointY(value: number): number;
82
+ /**
83
+ * A point's x as a percentage of the host's width. The x-label strip and the SVG share
84
+ * that width — the drawing stretches to it — so this is the same space the tooltip and
85
+ * the labels are placed in, at any size.
86
+ */
87
+ protected xPercent(index: number): number;
88
+ /**
89
+ * How wide an x label may be, as a percentage of the host's width: its own slot — half
90
+ * the distance to a neighbour on each side — cut back to what is left between its point
91
+ * and the end of the strip. Centring a label on its point says nothing about its WIDTH,
92
+ * and with no bound at all twelve month names printed over each other and the last one
93
+ * hung outside the chart. Past this the stylesheet ellipsises.
94
+ */
95
+ protected xMaxPercent(index: number): number;
79
96
  protected readonly hoverPoints: _angular_core.Signal<{
80
97
  label: string;
81
98
  value: number;
@@ -387,6 +387,17 @@ declare class WrMarkdownHighlight {
387
387
  private fill;
388
388
  /** `Map` iterates in insertion order, and `linesFor` re-inserts on read. */
389
389
  private evict;
390
+ /**
391
+ * The same bound, one dimension out. `request` re-inserts a bucket it already
392
+ * holds, so the outer map iterates least-recently-REQUESTED first — and the
393
+ * component's effect asks for every code block in the document it is showing,
394
+ * so a language that stops being requested is one nothing renders any more.
395
+ *
396
+ * Read is deliberately NOT a touch here, unlike {@link linesFor} for the inner
397
+ * map: with the effect re-asking for every block, request order already tracks
398
+ * what is rendered, and nothing has needed the finer signal.
399
+ */
400
+ private evictLanguage;
390
401
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrMarkdownHighlight, never>;
391
402
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<WrMarkdownHighlight>;
392
403
  }