ngwr 14.7.0 → 14.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (482) hide show
  1. package/README.md +66 -332
  2. package/alert/styles/_index.scss +10 -0
  3. package/avatar/styles/_index.scss +18 -7
  4. package/badge/styles/_index.scss +7 -0
  5. package/badge/styles/_tag.scss +7 -1
  6. package/bar-chart/styles/_index.scss +1 -0
  7. package/button/styles/_index.scss +6 -0
  8. package/calendar-heatmap/styles/_index.scss +1 -0
  9. package/cascader/styles/_rules.scss +87 -15
  10. package/checkbox/styles/_index.scss +4 -0
  11. package/command-palette/styles/_index.scss +1 -1
  12. package/date-picker/styles/_index.scss +30 -0
  13. package/density/styles/_index.scss +4 -2
  14. package/divider/styles/_index.scss +2 -0
  15. package/donut-chart/styles/_index.scss +10 -0
  16. package/dropdown/styles/_index.scss +67 -5
  17. package/editor/styles/_index.scss +441 -0
  18. package/event-calendar/styles/_index.scss +209 -35
  19. package/fesm2022/ngwr-action-sheet-testing.mjs.map +1 -1
  20. package/fesm2022/ngwr-action-sheet.mjs +3 -3
  21. package/fesm2022/ngwr-action-sheet.mjs.map +1 -1
  22. package/fesm2022/ngwr-affix.mjs +3 -3
  23. package/fesm2022/ngwr-affix.mjs.map +1 -1
  24. package/fesm2022/ngwr-alert.mjs +3 -3
  25. package/fesm2022/ngwr-alert.mjs.map +1 -1
  26. package/fesm2022/ngwr-anchor.mjs +3 -3
  27. package/fesm2022/ngwr-anchor.mjs.map +1 -1
  28. package/fesm2022/ngwr-aurora.mjs +3 -3
  29. package/fesm2022/ngwr-aurora.mjs.map +1 -1
  30. package/fesm2022/ngwr-avatar.mjs +3 -3
  31. package/fesm2022/ngwr-avatar.mjs.map +1 -1
  32. package/fesm2022/ngwr-back-top.mjs +3 -3
  33. package/fesm2022/ngwr-back-top.mjs.map +1 -1
  34. package/fesm2022/ngwr-badge.mjs +28 -13
  35. package/fesm2022/ngwr-badge.mjs.map +1 -1
  36. package/fesm2022/ngwr-bar-chart-testing.mjs.map +1 -1
  37. package/fesm2022/ngwr-bar-chart.mjs +31 -6
  38. package/fesm2022/ngwr-bar-chart.mjs.map +1 -1
  39. package/fesm2022/ngwr-blur-text-testing.mjs.map +1 -1
  40. package/fesm2022/ngwr-blur-text.mjs +3 -3
  41. package/fesm2022/ngwr-blur-text.mjs.map +1 -1
  42. package/fesm2022/ngwr-border-glow-testing.mjs.map +1 -1
  43. package/fesm2022/ngwr-border-glow.mjs +3 -3
  44. package/fesm2022/ngwr-border-glow.mjs.map +1 -1
  45. package/fesm2022/ngwr-breadcrumbs.mjs +6 -6
  46. package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
  47. package/fesm2022/ngwr-burger.mjs +3 -3
  48. package/fesm2022/ngwr-burger.mjs.map +1 -1
  49. package/fesm2022/ngwr-button-testing.mjs.map +1 -1
  50. package/fesm2022/ngwr-button.mjs +6 -6
  51. package/fesm2022/ngwr-button.mjs.map +1 -1
  52. package/fesm2022/ngwr-calendar-heatmap-testing.mjs.map +1 -1
  53. package/fesm2022/ngwr-calendar-heatmap.mjs +61 -6
  54. package/fesm2022/ngwr-calendar-heatmap.mjs.map +1 -1
  55. package/fesm2022/ngwr-calendar-testing.mjs.map +1 -1
  56. package/fesm2022/ngwr-calendar.mjs +3 -3
  57. package/fesm2022/ngwr-calendar.mjs.map +1 -1
  58. package/fesm2022/ngwr-card.mjs +9 -9
  59. package/fesm2022/ngwr-card.mjs.map +1 -1
  60. package/fesm2022/ngwr-carousel-testing.mjs.map +1 -1
  61. package/fesm2022/ngwr-carousel.mjs +6 -6
  62. package/fesm2022/ngwr-carousel.mjs.map +1 -1
  63. package/fesm2022/ngwr-cascader-testing.mjs.map +1 -1
  64. package/fesm2022/ngwr-cascader.mjs +4 -4
  65. package/fesm2022/ngwr-cascader.mjs.map +1 -1
  66. package/fesm2022/ngwr-checkbox-testing.mjs.map +1 -1
  67. package/fesm2022/ngwr-checkbox.mjs +18 -8
  68. package/fesm2022/ngwr-checkbox.mjs.map +1 -1
  69. package/fesm2022/ngwr-circular-text-testing.mjs.map +1 -1
  70. package/fesm2022/ngwr-circular-text.mjs +3 -3
  71. package/fesm2022/ngwr-circular-text.mjs.map +1 -1
  72. package/fesm2022/ngwr-click-spark.mjs +3 -3
  73. package/fesm2022/ngwr-click-spark.mjs.map +1 -1
  74. package/fesm2022/ngwr-clipboard.mjs +3 -3
  75. package/fesm2022/ngwr-clipboard.mjs.map +1 -1
  76. package/fesm2022/ngwr-collapse-testing.mjs.map +1 -1
  77. package/fesm2022/ngwr-collapse.mjs +9 -9
  78. package/fesm2022/ngwr-collapse.mjs.map +1 -1
  79. package/fesm2022/ngwr-color-picker-testing.mjs.map +1 -1
  80. package/fesm2022/ngwr-color-picker.mjs +6 -6
  81. package/fesm2022/ngwr-color-picker.mjs.map +1 -1
  82. package/fesm2022/ngwr-command-palette-testing.mjs.map +1 -1
  83. package/fesm2022/ngwr-command-palette.mjs +3 -3
  84. package/fesm2022/ngwr-command-palette.mjs.map +1 -1
  85. package/fesm2022/ngwr-compare.mjs +3 -3
  86. package/fesm2022/ngwr-compare.mjs.map +1 -1
  87. package/fesm2022/ngwr-confetti.mjs +3 -3
  88. package/fesm2022/ngwr-confetti.mjs.map +1 -1
  89. package/fesm2022/ngwr-config.mjs.map +1 -1
  90. package/fesm2022/ngwr-context-menu-testing.mjs.map +1 -1
  91. package/fesm2022/ngwr-context-menu.mjs +12 -12
  92. package/fesm2022/ngwr-context-menu.mjs.map +1 -1
  93. package/fesm2022/ngwr-cookie.mjs +3 -3
  94. package/fesm2022/ngwr-cookie.mjs.map +1 -1
  95. package/fesm2022/ngwr-counter.mjs +6 -6
  96. package/fesm2022/ngwr-counter.mjs.map +1 -1
  97. package/fesm2022/ngwr-date-adapters-fns.mjs +3 -3
  98. package/fesm2022/ngwr-date-adapters-fns.mjs.map +1 -1
  99. package/fesm2022/ngwr-date-adapters-luxon.mjs +3 -3
  100. package/fesm2022/ngwr-date-adapters-luxon.mjs.map +1 -1
  101. package/fesm2022/ngwr-date-picker-testing.mjs.map +1 -1
  102. package/fesm2022/ngwr-date-picker.mjs +721 -62
  103. package/fesm2022/ngwr-date-picker.mjs.map +1 -1
  104. package/fesm2022/ngwr-date.mjs +3 -3
  105. package/fesm2022/ngwr-date.mjs.map +1 -1
  106. package/fesm2022/ngwr-decrypt-text-testing.mjs.map +1 -1
  107. package/fesm2022/ngwr-decrypt-text.mjs +3 -3
  108. package/fesm2022/ngwr-decrypt-text.mjs.map +1 -1
  109. package/fesm2022/ngwr-density.mjs +6 -6
  110. package/fesm2022/ngwr-density.mjs.map +1 -1
  111. package/fesm2022/ngwr-descriptions.mjs +6 -6
  112. package/fesm2022/ngwr-descriptions.mjs.map +1 -1
  113. package/fesm2022/ngwr-dialog-testing.mjs.map +1 -1
  114. package/fesm2022/ngwr-dialog.mjs +15 -15
  115. package/fesm2022/ngwr-dialog.mjs.map +1 -1
  116. package/fesm2022/ngwr-directives.mjs +12 -12
  117. package/fesm2022/ngwr-directives.mjs.map +1 -1
  118. package/fesm2022/ngwr-divider.mjs +3 -3
  119. package/fesm2022/ngwr-divider.mjs.map +1 -1
  120. package/fesm2022/ngwr-donut-chart-testing.mjs.map +1 -1
  121. package/fesm2022/ngwr-donut-chart.mjs +48 -6
  122. package/fesm2022/ngwr-donut-chart.mjs.map +1 -1
  123. package/fesm2022/ngwr-drag-drop.mjs +6 -6
  124. package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
  125. package/fesm2022/ngwr-drawer-testing.mjs.map +1 -1
  126. package/fesm2022/ngwr-drawer.mjs +18 -18
  127. package/fesm2022/ngwr-drawer.mjs.map +1 -1
  128. package/fesm2022/ngwr-dropdown-testing.mjs.map +1 -1
  129. package/fesm2022/ngwr-dropdown.mjs +174 -25
  130. package/fesm2022/ngwr-dropdown.mjs.map +1 -1
  131. package/fesm2022/ngwr-editor-testing.mjs +568 -0
  132. package/fesm2022/ngwr-editor-testing.mjs.map +1 -0
  133. package/fesm2022/ngwr-editor.mjs +2601 -0
  134. package/fesm2022/ngwr-editor.mjs.map +1 -0
  135. package/fesm2022/ngwr-empty.mjs +3 -3
  136. package/fesm2022/ngwr-empty.mjs.map +1 -1
  137. package/fesm2022/ngwr-event-calendar-testing.mjs.map +1 -1
  138. package/fesm2022/ngwr-event-calendar.mjs +14 -7
  139. package/fesm2022/ngwr-event-calendar.mjs.map +1 -1
  140. package/fesm2022/ngwr-falling-text-testing.mjs.map +1 -1
  141. package/fesm2022/ngwr-falling-text.mjs +3 -3
  142. package/fesm2022/ngwr-falling-text.mjs.map +1 -1
  143. package/fesm2022/ngwr-file-upload-testing.mjs.map +1 -1
  144. package/fesm2022/ngwr-file-upload.mjs +3 -3
  145. package/fesm2022/ngwr-file-upload.mjs.map +1 -1
  146. package/fesm2022/ngwr-form-testing.mjs.map +1 -1
  147. package/fesm2022/ngwr-form.mjs +61 -10
  148. package/fesm2022/ngwr-form.mjs.map +1 -1
  149. package/fesm2022/ngwr-fuzzy-text-testing.mjs.map +1 -1
  150. package/fesm2022/ngwr-fuzzy-text.mjs +3 -3
  151. package/fesm2022/ngwr-fuzzy-text.mjs.map +1 -1
  152. package/fesm2022/ngwr-gauge-testing.mjs.map +1 -1
  153. package/fesm2022/ngwr-gauge.mjs +35 -6
  154. package/fesm2022/ngwr-gauge.mjs.map +1 -1
  155. package/fesm2022/ngwr-glitch-text-testing.mjs.map +1 -1
  156. package/fesm2022/ngwr-glitch-text.mjs +3 -3
  157. package/fesm2022/ngwr-glitch-text.mjs.map +1 -1
  158. package/fesm2022/ngwr-gradient-text-testing.mjs.map +1 -1
  159. package/fesm2022/ngwr-gradient-text.mjs +3 -3
  160. package/fesm2022/ngwr-gradient-text.mjs.map +1 -1
  161. package/fesm2022/ngwr-graph-testing.mjs.map +1 -1
  162. package/fesm2022/ngwr-graph.mjs +6 -6
  163. package/fesm2022/ngwr-graph.mjs.map +1 -1
  164. package/fesm2022/ngwr-hotkey.mjs +6 -6
  165. package/fesm2022/ngwr-hotkey.mjs.map +1 -1
  166. package/fesm2022/ngwr-i18n-ar.mjs +31 -0
  167. package/fesm2022/ngwr-i18n-ar.mjs.map +1 -1
  168. package/fesm2022/ngwr-i18n-cs.mjs +31 -0
  169. package/fesm2022/ngwr-i18n-cs.mjs.map +1 -1
  170. package/fesm2022/ngwr-i18n-de.mjs +31 -0
  171. package/fesm2022/ngwr-i18n-de.mjs.map +1 -1
  172. package/fesm2022/ngwr-i18n-en.mjs +39 -0
  173. package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
  174. package/fesm2022/ngwr-i18n-es.mjs +31 -0
  175. package/fesm2022/ngwr-i18n-es.mjs.map +1 -1
  176. package/fesm2022/ngwr-i18n-fr.mjs +31 -0
  177. package/fesm2022/ngwr-i18n-fr.mjs.map +1 -1
  178. package/fesm2022/ngwr-i18n-he.mjs +31 -0
  179. package/fesm2022/ngwr-i18n-he.mjs.map +1 -1
  180. package/fesm2022/ngwr-i18n-hi.mjs +31 -0
  181. package/fesm2022/ngwr-i18n-hi.mjs.map +1 -1
  182. package/fesm2022/ngwr-i18n-id.mjs +31 -0
  183. package/fesm2022/ngwr-i18n-id.mjs.map +1 -1
  184. package/fesm2022/ngwr-i18n-it.mjs +31 -0
  185. package/fesm2022/ngwr-i18n-it.mjs.map +1 -1
  186. package/fesm2022/ngwr-i18n-ja.mjs +31 -0
  187. package/fesm2022/ngwr-i18n-ja.mjs.map +1 -1
  188. package/fesm2022/ngwr-i18n-ko.mjs +31 -0
  189. package/fesm2022/ngwr-i18n-ko.mjs.map +1 -1
  190. package/fesm2022/ngwr-i18n-nl.mjs +31 -0
  191. package/fesm2022/ngwr-i18n-nl.mjs.map +1 -1
  192. package/fesm2022/ngwr-i18n-pl.mjs +31 -0
  193. package/fesm2022/ngwr-i18n-pl.mjs.map +1 -1
  194. package/fesm2022/ngwr-i18n-pt.mjs +31 -0
  195. package/fesm2022/ngwr-i18n-pt.mjs.map +1 -1
  196. package/fesm2022/ngwr-i18n-ru.mjs +31 -0
  197. package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
  198. package/fesm2022/ngwr-i18n-sv.mjs +31 -0
  199. package/fesm2022/ngwr-i18n-sv.mjs.map +1 -1
  200. package/fesm2022/ngwr-i18n-tr.mjs +31 -0
  201. package/fesm2022/ngwr-i18n-tr.mjs.map +1 -1
  202. package/fesm2022/ngwr-i18n-uk.mjs +31 -0
  203. package/fesm2022/ngwr-i18n-uk.mjs.map +1 -1
  204. package/fesm2022/ngwr-i18n-vi.mjs +31 -0
  205. package/fesm2022/ngwr-i18n-vi.mjs.map +1 -1
  206. package/fesm2022/ngwr-i18n-zh-TW.mjs +31 -0
  207. package/fesm2022/ngwr-i18n-zh-TW.mjs.map +1 -1
  208. package/fesm2022/ngwr-i18n-zh.mjs +31 -0
  209. package/fesm2022/ngwr-i18n-zh.mjs.map +1 -1
  210. package/fesm2022/ngwr-i18n.mjs +9 -9
  211. package/fesm2022/ngwr-i18n.mjs.map +1 -1
  212. package/fesm2022/ngwr-icon-adapters-feather.mjs.map +1 -1
  213. package/fesm2022/ngwr-icon-adapters-lucide.mjs.map +1 -1
  214. package/fesm2022/ngwr-icon.mjs +6 -6
  215. package/fesm2022/ngwr-icon.mjs.map +1 -1
  216. package/fesm2022/ngwr-image-cropper-testing.mjs.map +1 -1
  217. package/fesm2022/ngwr-image-cropper.mjs +3 -3
  218. package/fesm2022/ngwr-image-cropper.mjs.map +1 -1
  219. package/fesm2022/ngwr-input-number-testing.mjs.map +1 -1
  220. package/fesm2022/ngwr-input-number.mjs +15 -3
  221. package/fesm2022/ngwr-input-number.mjs.map +1 -1
  222. package/fesm2022/ngwr-input-otp-testing.mjs.map +1 -1
  223. package/fesm2022/ngwr-input-otp.mjs +3 -3
  224. package/fesm2022/ngwr-input-otp.mjs.map +1 -1
  225. package/fesm2022/ngwr-input-testing.mjs.map +1 -1
  226. package/fesm2022/ngwr-input.mjs +15 -15
  227. package/fesm2022/ngwr-input.mjs.map +1 -1
  228. package/fesm2022/ngwr-keyboard.mjs +3 -3
  229. package/fesm2022/ngwr-keyboard.mjs.map +1 -1
  230. package/fesm2022/ngwr-knob-testing.mjs.map +1 -1
  231. package/fesm2022/ngwr-knob.mjs +3 -3
  232. package/fesm2022/ngwr-knob.mjs.map +1 -1
  233. package/fesm2022/ngwr-layout.mjs +15 -15
  234. package/fesm2022/ngwr-layout.mjs.map +1 -1
  235. package/fesm2022/ngwr-lightbox-testing.mjs.map +1 -1
  236. package/fesm2022/ngwr-lightbox.mjs +3 -3
  237. package/fesm2022/ngwr-lightbox.mjs.map +1 -1
  238. package/fesm2022/ngwr-line-chart-testing.mjs.map +1 -1
  239. package/fesm2022/ngwr-line-chart.mjs +18 -7
  240. package/fesm2022/ngwr-line-chart.mjs.map +1 -1
  241. package/fesm2022/ngwr-list.mjs +6 -6
  242. package/fesm2022/ngwr-list.mjs.map +1 -1
  243. package/fesm2022/ngwr-loading-bar-router.mjs.map +1 -1
  244. package/fesm2022/ngwr-loading-bar.mjs +6 -6
  245. package/fesm2022/ngwr-loading-bar.mjs.map +1 -1
  246. package/fesm2022/ngwr-markdown-testing.mjs.map +1 -1
  247. package/fesm2022/ngwr-markdown.mjs +798 -17
  248. package/fesm2022/ngwr-markdown.mjs.map +1 -1
  249. package/fesm2022/ngwr-marquee-testing.mjs.map +1 -1
  250. package/fesm2022/ngwr-marquee.mjs +3 -3
  251. package/fesm2022/ngwr-marquee.mjs.map +1 -1
  252. package/fesm2022/ngwr-media.mjs +3 -3
  253. package/fesm2022/ngwr-media.mjs.map +1 -1
  254. package/fesm2022/ngwr-mention-testing.mjs.map +1 -1
  255. package/fesm2022/ngwr-mention.mjs +6 -6
  256. package/fesm2022/ngwr-mention.mjs.map +1 -1
  257. package/fesm2022/ngwr-meta.mjs +6 -6
  258. package/fesm2022/ngwr-meta.mjs.map +1 -1
  259. package/fesm2022/ngwr-meter-group-testing.mjs +7 -3
  260. package/fesm2022/ngwr-meter-group-testing.mjs.map +1 -1
  261. package/fesm2022/ngwr-meter-group.mjs +26 -6
  262. package/fesm2022/ngwr-meter-group.mjs.map +1 -1
  263. package/fesm2022/ngwr-overlay.mjs +6 -6
  264. package/fesm2022/ngwr-overlay.mjs.map +1 -1
  265. package/fesm2022/ngwr-page-header.mjs +13 -5
  266. package/fesm2022/ngwr-page-header.mjs.map +1 -1
  267. package/fesm2022/ngwr-pagination-testing.mjs.map +1 -1
  268. package/fesm2022/ngwr-pagination.mjs +3 -3
  269. package/fesm2022/ngwr-pagination.mjs.map +1 -1
  270. package/fesm2022/ngwr-pipes.mjs +21 -21
  271. package/fesm2022/ngwr-pipes.mjs.map +1 -1
  272. package/fesm2022/ngwr-platform.mjs +9 -9
  273. package/fesm2022/ngwr-platform.mjs.map +1 -1
  274. package/fesm2022/ngwr-popconfirm-testing.mjs.map +1 -1
  275. package/fesm2022/ngwr-popconfirm.mjs +6 -6
  276. package/fesm2022/ngwr-popconfirm.mjs.map +1 -1
  277. package/fesm2022/ngwr-popover-testing.mjs.map +1 -1
  278. package/fesm2022/ngwr-popover.mjs +578 -16
  279. package/fesm2022/ngwr-popover.mjs.map +1 -1
  280. package/fesm2022/ngwr-progress.mjs +3 -3
  281. package/fesm2022/ngwr-progress.mjs.map +1 -1
  282. package/fesm2022/ngwr-pull-to-refresh.mjs +3 -3
  283. package/fesm2022/ngwr-pull-to-refresh.mjs.map +1 -1
  284. package/fesm2022/ngwr-qr.mjs +3 -3
  285. package/fesm2022/ngwr-qr.mjs.map +1 -1
  286. package/fesm2022/ngwr-radio-testing.mjs.map +1 -1
  287. package/fesm2022/ngwr-radio.mjs +6 -6
  288. package/fesm2022/ngwr-radio.mjs.map +1 -1
  289. package/fesm2022/ngwr-rating-testing.mjs.map +1 -1
  290. package/fesm2022/ngwr-rating.mjs +3 -3
  291. package/fesm2022/ngwr-rating.mjs.map +1 -1
  292. package/fesm2022/ngwr-result.mjs +12 -12
  293. package/fesm2022/ngwr-result.mjs.map +1 -1
  294. package/fesm2022/ngwr-rotating-text-testing.mjs.map +1 -1
  295. package/fesm2022/ngwr-rotating-text.mjs +3 -3
  296. package/fesm2022/ngwr-rotating-text.mjs.map +1 -1
  297. package/fesm2022/ngwr-schema-form.mjs +3 -3
  298. package/fesm2022/ngwr-schema-form.mjs.map +1 -1
  299. package/fesm2022/ngwr-scroll.mjs +3 -3
  300. package/fesm2022/ngwr-scroll.mjs.map +1 -1
  301. package/fesm2022/ngwr-segmented-testing.mjs.map +1 -1
  302. package/fesm2022/ngwr-segmented.mjs +3 -3
  303. package/fesm2022/ngwr-segmented.mjs.map +1 -1
  304. package/fesm2022/ngwr-select-testing.mjs.map +1 -1
  305. package/fesm2022/ngwr-select.mjs +12 -12
  306. package/fesm2022/ngwr-select.mjs.map +1 -1
  307. package/fesm2022/ngwr-shiny-text-testing.mjs.map +1 -1
  308. package/fesm2022/ngwr-shiny-text.mjs +6 -6
  309. package/fesm2022/ngwr-shiny-text.mjs.map +1 -1
  310. package/fesm2022/ngwr-sidebar.mjs +10 -3
  311. package/fesm2022/ngwr-sidebar.mjs.map +1 -1
  312. package/fesm2022/ngwr-skeleton.mjs +3 -3
  313. package/fesm2022/ngwr-skeleton.mjs.map +1 -1
  314. package/fesm2022/ngwr-slider-testing.mjs.map +1 -1
  315. package/fesm2022/ngwr-slider.mjs +3 -3
  316. package/fesm2022/ngwr-slider.mjs.map +1 -1
  317. package/fesm2022/ngwr-sparkline-testing.mjs.map +1 -1
  318. package/fesm2022/ngwr-sparkline.mjs +84 -10
  319. package/fesm2022/ngwr-sparkline.mjs.map +1 -1
  320. package/fesm2022/ngwr-speed-dial-testing.mjs.map +1 -1
  321. package/fesm2022/ngwr-speed-dial.mjs +3 -3
  322. package/fesm2022/ngwr-speed-dial.mjs.map +1 -1
  323. package/fesm2022/ngwr-spinner.mjs +3 -3
  324. package/fesm2022/ngwr-spinner.mjs.map +1 -1
  325. package/fesm2022/ngwr-splash-cursor-testing.mjs.map +1 -1
  326. package/fesm2022/ngwr-splash-cursor.mjs +3 -3
  327. package/fesm2022/ngwr-splash-cursor.mjs.map +1 -1
  328. package/fesm2022/ngwr-split-text-testing.mjs.map +1 -1
  329. package/fesm2022/ngwr-split-text.mjs +3 -3
  330. package/fesm2022/ngwr-split-text.mjs.map +1 -1
  331. package/fesm2022/ngwr-splitter-testing.mjs.map +1 -1
  332. package/fesm2022/ngwr-splitter.mjs +3 -3
  333. package/fesm2022/ngwr-splitter.mjs.map +1 -1
  334. package/fesm2022/ngwr-spotlight-card-testing.mjs.map +1 -1
  335. package/fesm2022/ngwr-spotlight-card.mjs +6 -6
  336. package/fesm2022/ngwr-spotlight-card.mjs.map +1 -1
  337. package/fesm2022/ngwr-squircle.mjs +6 -6
  338. package/fesm2022/ngwr-squircle.mjs.map +1 -1
  339. package/fesm2022/ngwr-star-border-testing.mjs.map +1 -1
  340. package/fesm2022/ngwr-star-border.mjs +3 -3
  341. package/fesm2022/ngwr-star-border.mjs.map +1 -1
  342. package/fesm2022/ngwr-statistic.mjs +9 -9
  343. package/fesm2022/ngwr-statistic.mjs.map +1 -1
  344. package/fesm2022/ngwr-stepper-testing.mjs.map +1 -1
  345. package/fesm2022/ngwr-stepper.mjs +6 -6
  346. package/fesm2022/ngwr-stepper.mjs.map +1 -1
  347. package/fesm2022/ngwr-storage.mjs +3 -3
  348. package/fesm2022/ngwr-storage.mjs.map +1 -1
  349. package/fesm2022/ngwr-switch-testing.mjs.map +1 -1
  350. package/fesm2022/ngwr-switch.mjs +3 -3
  351. package/fesm2022/ngwr-switch.mjs.map +1 -1
  352. package/fesm2022/ngwr-table-testing.mjs.map +1 -1
  353. package/fesm2022/ngwr-table.mjs +18 -18
  354. package/fesm2022/ngwr-table.mjs.map +1 -1
  355. package/fesm2022/ngwr-tabs-router.mjs +3 -3
  356. package/fesm2022/ngwr-tabs-router.mjs.map +1 -1
  357. package/fesm2022/ngwr-tabs-testing.mjs.map +1 -1
  358. package/fesm2022/ngwr-tabs.mjs +6 -6
  359. package/fesm2022/ngwr-tabs.mjs.map +1 -1
  360. package/fesm2022/ngwr-textarea-testing.mjs.map +1 -1
  361. package/fesm2022/ngwr-textarea.mjs +3 -3
  362. package/fesm2022/ngwr-textarea.mjs.map +1 -1
  363. package/fesm2022/ngwr-theme.mjs +3 -3
  364. package/fesm2022/ngwr-theme.mjs.map +1 -1
  365. package/fesm2022/ngwr-tilt-card-testing.mjs.map +1 -1
  366. package/fesm2022/ngwr-tilt-card.mjs +6 -6
  367. package/fesm2022/ngwr-tilt-card.mjs.map +1 -1
  368. package/fesm2022/ngwr-timeline.mjs +6 -6
  369. package/fesm2022/ngwr-timeline.mjs.map +1 -1
  370. package/fesm2022/ngwr-toast-testing.mjs.map +1 -1
  371. package/fesm2022/ngwr-toast.mjs +9 -9
  372. package/fesm2022/ngwr-toast.mjs.map +1 -1
  373. package/fesm2022/ngwr-toolbar.mjs +10 -3
  374. package/fesm2022/ngwr-toolbar.mjs.map +1 -1
  375. package/fesm2022/ngwr-tour-testing.mjs.map +1 -1
  376. package/fesm2022/ngwr-tour.mjs +6 -6
  377. package/fesm2022/ngwr-tour.mjs.map +1 -1
  378. package/fesm2022/ngwr-transfer-testing.mjs.map +1 -1
  379. package/fesm2022/ngwr-transfer.mjs +3 -3
  380. package/fesm2022/ngwr-transfer.mjs.map +1 -1
  381. package/fesm2022/ngwr-tree-testing.mjs.map +1 -1
  382. package/fesm2022/ngwr-tree.mjs +3 -3
  383. package/fesm2022/ngwr-tree.mjs.map +1 -1
  384. package/fesm2022/ngwr-typewriter-testing.mjs.map +1 -1
  385. package/fesm2022/ngwr-typewriter.mjs +3 -3
  386. package/fesm2022/ngwr-typewriter.mjs.map +1 -1
  387. package/fesm2022/ngwr-typography.mjs +7 -3
  388. package/fesm2022/ngwr-typography.mjs.map +1 -1
  389. package/fesm2022/ngwr-utils.mjs.map +1 -1
  390. package/fesm2022/ngwr-validators.mjs.map +1 -1
  391. package/fesm2022/ngwr-version.mjs +1 -1
  392. package/fesm2022/ngwr-version.mjs.map +1 -1
  393. package/fesm2022/ngwr-virtual-scroll.mjs +3 -3
  394. package/fesm2022/ngwr-virtual-scroll.mjs.map +1 -1
  395. package/fesm2022/ngwr-waves-testing.mjs.map +1 -1
  396. package/fesm2022/ngwr-waves.mjs +3 -3
  397. package/fesm2022/ngwr-waves.mjs.map +1 -1
  398. package/fesm2022/ngwr-window-testing.mjs.map +1 -1
  399. package/fesm2022/ngwr-window.mjs +12 -12
  400. package/fesm2022/ngwr-window.mjs.map +1 -1
  401. package/form/styles/_index.scss +16 -1
  402. package/gauge/styles/_index.scss +1 -0
  403. package/i18n/ar.json +32 -1
  404. package/i18n/cs.json +32 -1
  405. package/i18n/de.json +32 -1
  406. package/i18n/en.json +32 -1
  407. package/i18n/es.json +32 -1
  408. package/i18n/fr.json +32 -1
  409. package/i18n/he.json +32 -1
  410. package/i18n/hi.json +32 -1
  411. package/i18n/id.json +32 -1
  412. package/i18n/it.json +32 -1
  413. package/i18n/ja.json +32 -1
  414. package/i18n/ko.json +32 -1
  415. package/i18n/nl.json +32 -1
  416. package/i18n/pl.json +32 -1
  417. package/i18n/pt.json +32 -1
  418. package/i18n/ru.json +32 -1
  419. package/i18n/sv.json +32 -1
  420. package/i18n/tr.json +32 -1
  421. package/i18n/uk.json +32 -1
  422. package/i18n/vi.json +32 -1
  423. package/i18n/zh-TW.json +32 -1
  424. package/i18n/zh.json +32 -1
  425. package/input/styles/_index.scss +24 -1
  426. package/input-number/styles/_index.scss +69 -0
  427. package/input-otp/styles/_index.scss +5 -5
  428. package/line-chart/styles/_index.scss +30 -2
  429. package/llms-full.txt +14 -4
  430. package/llms.txt +188 -132
  431. package/mcp/providers.js +2 -2
  432. package/mcp/server.js +1 -1
  433. package/meter-group/styles/_index.scss +1 -0
  434. package/overlay/styles/_arrow.scss +30 -2
  435. package/package.json +43 -2
  436. package/page-header/styles/_index.scss +37 -1
  437. package/pagination/styles/_index.scss +9 -5
  438. package/popover/styles/_index.scss +73 -5
  439. package/progress/styles/_index.scss +4 -0
  440. package/radio/styles/_index.scss +4 -1
  441. package/schematics/use/symbol-map.json +1 -0
  442. package/select/styles/_index.scss +51 -12
  443. package/sidebar/styles/_index.scss +44 -2
  444. package/skeleton/styles/_index.scss +3 -0
  445. package/skills/ngwr/SKILL.md +5 -5
  446. package/skills/ngwr/references/catalog.md +2 -0
  447. package/skills/ngwr/references/setup.md +3 -3
  448. package/sparkline/styles/_index.scss +19 -0
  449. package/styles.scss +1 -0
  450. package/table/styles/_index.scss +7 -0
  451. package/textarea/styles/_index.scss +12 -3
  452. package/theme/styles/_colors.scss +39 -13
  453. package/theme/styles/_contrast.scss +9 -7
  454. package/toast/styles/_index.scss +4 -0
  455. package/toolbar/styles/_index.scss +35 -1
  456. package/tree/styles/_index.scss +46 -7
  457. package/types/ngwr-badge.d.ts +22 -7
  458. package/types/ngwr-bar-chart.d.ts +19 -1
  459. package/types/ngwr-calendar-heatmap.d.ts +29 -1
  460. package/types/ngwr-checkbox.d.ts +2 -0
  461. package/types/ngwr-config.d.ts +12 -0
  462. package/types/ngwr-date-picker.d.ts +308 -43
  463. package/types/ngwr-donut-chart.d.ts +24 -1
  464. package/types/ngwr-dropdown.d.ts +22 -2
  465. package/types/ngwr-editor-testing.d.ts +378 -0
  466. package/types/ngwr-editor.d.ts +449 -0
  467. package/types/ngwr-event-calendar.d.ts +8 -0
  468. package/types/ngwr-form.d.ts +35 -5
  469. package/types/ngwr-gauge.d.ts +20 -1
  470. package/types/ngwr-input-number.d.ts +7 -0
  471. package/types/ngwr-line-chart.d.ts +9 -1
  472. package/types/ngwr-markdown.d.ts +61 -2
  473. package/types/ngwr-meter-group-testing.d.ts +3 -2
  474. package/types/ngwr-meter-group.d.ts +14 -1
  475. package/types/ngwr-page-header.d.ts +10 -2
  476. package/types/ngwr-popover.d.ts +154 -3
  477. package/types/ngwr-sidebar.d.ts +7 -0
  478. package/types/ngwr-sparkline.d.ts +43 -1
  479. package/types/ngwr-toolbar.d.ts +7 -0
  480. package/types/ngwr-typography.d.ts +4 -0
  481. package/types/ngwr-version.d.ts +1 -1
  482. package/typography/styles/_index.scss +16 -0
@@ -1,8 +1,9 @@
1
1
  import { coerceNumberProperty, coerceBooleanProperty } from '@angular/cdk/coercion';
2
2
  import * as i0 from '@angular/core';
3
- import { input, inject, computed, ViewEncapsulation, Component } from '@angular/core';
3
+ import { input, viewChild, inject, computed, ViewEncapsulation, Component } from '@angular/core';
4
4
  import { WR_DATE_LOCALE } from 'ngwr/date';
5
5
  import { useI18nText, useI18nFormatter } from 'ngwr/i18n';
6
+ import { useChartTooltip } from 'ngwr/popover';
6
7
 
7
8
  /**
8
9
  * @license
@@ -95,6 +96,14 @@ class WrCalendarHeatmap {
95
96
  ...(ngDevMode ? [{ debugName: "emptyColor" }] : /* istanbul ignore next */ []));
96
97
  /** Show the weekday + month labels around the grid. @default true */
97
98
  showLabels = input(true, { ...(ngDevMode ? { debugName: "showLabels" } : /* istanbul ignore next */ {}), transform: coerceBooleanProperty });
99
+ /**
100
+ * Show a tooltip with the day and its count on hover. It is the sentence the
101
+ * square's `title` carried, so the `title` is written only while this is off —
102
+ * or the browser would open a second copy a moment later. @default true
103
+ */
104
+ tooltip = input(true, { ...(ngDevMode ? { debugName: "tooltip" } : /* istanbul ignore next */ {}), transform: coerceBooleanProperty });
105
+ daysEl = viewChild('days', /* @ts-ignore */
106
+ ...(ngDevMode ? [{ debugName: "daysEl" }] : /* istanbul ignore next */ []));
98
107
  locale = inject(WR_DATE_LOCALE);
99
108
  /**
100
109
  * Weekday names from the locale rather than a hard-coded English list — the row order is
@@ -184,6 +193,52 @@ class WrCalendarHeatmap {
184
193
  return cells.length === 0 ? 0 : cells[cells.length - 1].week + 1;
185
194
  }, /* @ts-ignore */
186
195
  ...(ngDevMode ? [{ debugName: "columnCount" }] : /* istanbul ignore next */ []));
196
+ /** Each day's position in `cells()`, for the square the pointer lands on. */
197
+ indexByIso = computed(() => new Map(this.cells().map((cell, index) => [cell.iso, index])), /* @ts-ignore */
198
+ ...(ngDevMode ? [{ debugName: "indexByIso" }] : /* istanbul ignore next */ []));
199
+ /**
200
+ * One tooltip for the whole year, pointing at the hovered day: above its square,
201
+ * below it when there is no room above, and slid along the viewport edge for the
202
+ * first and last weeks with the arrow still on the square. A listener on the grid
203
+ * rather than one per square: a year is 371 of them.
204
+ *
205
+ * The box is the square's LAYOUT box rather than its client rect. The hovered square
206
+ * grows by `:hover` over a transition, and a rect read part way through it would
207
+ * move the chip by up to a fifth of a square depending on when it was measured;
208
+ * the scale is centred, so the layout box is the rect's centre and the square's
209
+ * own size.
210
+ */
211
+ tip = useChartTooltip(this.tooltip, index => {
212
+ const cell = this.cells()[index];
213
+ // The squares are the container's only children, drawn in `cells()` order.
214
+ const square = cell ? this.daysEl()?.nativeElement.children.item(index) : null;
215
+ if (!cell || !(square instanceof HTMLElement))
216
+ return null;
217
+ const rect = square.getBoundingClientRect();
218
+ const width = square.offsetWidth;
219
+ const height = square.offsetHeight;
220
+ return {
221
+ datum: { value: this.cellTitle(cell) },
222
+ anchor: {
223
+ x: (rect.left + rect.right - width) / 2,
224
+ y: (rect.top + rect.bottom - height) / 2,
225
+ width,
226
+ height,
227
+ },
228
+ };
229
+ });
230
+ /**
231
+ * Which square the pointer is on, from a `mousemove` on the grid. Over the gap
232
+ * between two squares it is on none, and the tooltip starts to leave.
233
+ */
234
+ onCellsPointer(event) {
235
+ const iso = event.target?.closest('.wr-calendar-heatmap__cell')?.dataset['date'];
236
+ const index = iso === undefined ? undefined : this.indexByIso().get(iso);
237
+ if (index === undefined)
238
+ this.tip.leave(event);
239
+ else
240
+ this.tip.enter(index);
241
+ }
187
242
  colorFor(intensity) {
188
243
  if (intensity === 0)
189
244
  return this.emptyColor();
@@ -201,13 +256,13 @@ class WrCalendarHeatmap {
201
256
  return 0.75;
202
257
  return 1;
203
258
  }
204
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrCalendarHeatmap, deps: [], target: i0.ɵɵFactoryTarget.Component });
205
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: WrCalendarHeatmap, isStandalone: true, selector: "wr-calendar-heatmap", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, endDate: { classPropertyName: "endDate", publicName: "endDate", isSignal: true, isRequired: false, transformFunction: null }, weeks: { classPropertyName: "weeks", publicName: "weeks", isSignal: true, isRequired: false, transformFunction: null }, cellSize: { classPropertyName: "cellSize", publicName: "cellSize", isSignal: true, isRequired: false, transformFunction: null }, cellGap: { classPropertyName: "cellGap", publicName: "cellGap", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, emptyColor: { classPropertyName: "emptyColor", publicName: "emptyColor", isSignal: true, isRequired: false, transformFunction: null }, showLabels: { classPropertyName: "showLabels", publicName: "showLabels", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "wr-calendar-heatmap" }, ngImport: i0, template: "<div\n class=\"wr-calendar-heatmap__grid\"\n role=\"img\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\n [style.--wr-heatmap-cell-size.px]=\"cellSize()\"\n [style.--wr-heatmap-cell-gap.px]=\"cellGap()\"\n [style.--wr-heatmap-columns]=\"columnCount()\"\n>\n @if (showLabels()) {\n <div class=\"wr-calendar-heatmap__weekdays\">\n @for (label of weekdayLabels(); track $index) {\n <span class=\"wr-calendar-heatmap__weekday\">{{ label }}</span>\n }\n </div>\n }\n\n <div class=\"wr-calendar-heatmap__cells\">\n @for (cell of cells(); track cell.iso) {\n <span\n class=\"wr-calendar-heatmap__cell\"\n [style.background]=\"colorFor(cell.intensity)\"\n [style.opacity]=\"opacityFor(cell.intensity)\"\n [style.grid-column]=\"cell.week + 1\"\n [style.grid-row]=\"cell.day + 1\"\n [title]=\"cellTitle(cell)\"\n [attr.data-date]=\"cell.iso\"\n [attr.data-value]=\"cell.value\"\n aria-hidden=\"true\"\n ></span>\n }\n </div>\n\n @if (showLabels()) {\n <div class=\"wr-calendar-heatmap__months\">\n @for (m of monthLabels(); track $index) {\n <span class=\"wr-calendar-heatmap__month\" [style.grid-column]=\"m.week + 1\">{{ m.label }}</span>\n }\n </div>\n }\n</div>\n", encapsulation: i0.ViewEncapsulation.None });
259
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrCalendarHeatmap, deps: [], target: i0.ɵɵFactoryTarget.Component });
260
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: WrCalendarHeatmap, isStandalone: true, selector: "wr-calendar-heatmap", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, endDate: { classPropertyName: "endDate", publicName: "endDate", isSignal: true, isRequired: false, transformFunction: null }, weeks: { classPropertyName: "weeks", publicName: "weeks", isSignal: true, isRequired: false, transformFunction: null }, cellSize: { classPropertyName: "cellSize", publicName: "cellSize", isSignal: true, isRequired: false, transformFunction: null }, cellGap: { classPropertyName: "cellGap", publicName: "cellGap", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, emptyColor: { classPropertyName: "emptyColor", publicName: "emptyColor", isSignal: true, isRequired: false, transformFunction: null }, showLabels: { classPropertyName: "showLabels", publicName: "showLabels", isSignal: true, isRequired: false, transformFunction: null }, tooltip: { classPropertyName: "tooltip", publicName: "tooltip", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "wr-calendar-heatmap" }, viewQueries: [{ propertyName: "daysEl", first: true, predicate: ["days"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n class=\"wr-calendar-heatmap__grid\"\n role=\"img\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\n [style.--wr-heatmap-cell-size.px]=\"cellSize()\"\n [style.--wr-heatmap-cell-gap.px]=\"cellGap()\"\n [style.--wr-heatmap-columns]=\"columnCount()\"\n>\n @if (showLabels()) {\n <div class=\"wr-calendar-heatmap__weekdays\">\n @for (label of weekdayLabels(); track $index) {\n <span class=\"wr-calendar-heatmap__weekday\">{{ label }}</span>\n }\n </div>\n }\n\n <div #days class=\"wr-calendar-heatmap__cells\" (mousemove)=\"onCellsPointer($event)\" (mouseleave)=\"tip.leave($event)\">\n @for (cell of cells(); track cell.iso) {\n <span\n class=\"wr-calendar-heatmap__cell\"\n [style.background]=\"colorFor(cell.intensity)\"\n [style.opacity]=\"opacityFor(cell.intensity)\"\n [style.grid-column]=\"cell.week + 1\"\n [style.grid-row]=\"cell.day + 1\"\n [attr.title]=\"tooltip() ? null : cellTitle(cell)\"\n [attr.data-date]=\"cell.iso\"\n [attr.data-value]=\"cell.value\"\n aria-hidden=\"true\"\n ></span>\n }\n </div>\n\n @if (showLabels()) {\n <div class=\"wr-calendar-heatmap__months\">\n @for (m of monthLabels(); track $index) {\n <span class=\"wr-calendar-heatmap__month\" [style.grid-column]=\"m.week + 1\">{{ m.label }}</span>\n }\n </div>\n }\n</div>\n", encapsulation: i0.ViewEncapsulation.None });
206
261
  }
207
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrCalendarHeatmap, decorators: [{
262
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrCalendarHeatmap, decorators: [{
208
263
  type: Component,
209
- args: [{ selector: 'wr-calendar-heatmap', encapsulation: ViewEncapsulation.None, host: { class: 'wr-calendar-heatmap' }, template: "<div\n class=\"wr-calendar-heatmap__grid\"\n role=\"img\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\n [style.--wr-heatmap-cell-size.px]=\"cellSize()\"\n [style.--wr-heatmap-cell-gap.px]=\"cellGap()\"\n [style.--wr-heatmap-columns]=\"columnCount()\"\n>\n @if (showLabels()) {\n <div class=\"wr-calendar-heatmap__weekdays\">\n @for (label of weekdayLabels(); track $index) {\n <span class=\"wr-calendar-heatmap__weekday\">{{ label }}</span>\n }\n </div>\n }\n\n <div class=\"wr-calendar-heatmap__cells\">\n @for (cell of cells(); track cell.iso) {\n <span\n class=\"wr-calendar-heatmap__cell\"\n [style.background]=\"colorFor(cell.intensity)\"\n [style.opacity]=\"opacityFor(cell.intensity)\"\n [style.grid-column]=\"cell.week + 1\"\n [style.grid-row]=\"cell.day + 1\"\n [title]=\"cellTitle(cell)\"\n [attr.data-date]=\"cell.iso\"\n [attr.data-value]=\"cell.value\"\n aria-hidden=\"true\"\n ></span>\n }\n </div>\n\n @if (showLabels()) {\n <div class=\"wr-calendar-heatmap__months\">\n @for (m of monthLabels(); track $index) {\n <span class=\"wr-calendar-heatmap__month\" [style.grid-column]=\"m.week + 1\">{{ m.label }}</span>\n }\n </div>\n }\n</div>\n" }]
210
- }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], endDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "endDate", required: false }] }], weeks: [{ type: i0.Input, args: [{ isSignal: true, alias: "weeks", required: false }] }], cellSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellSize", required: false }] }], cellGap: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellGap", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], emptyColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyColor", required: false }] }], showLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLabels", required: false }] }] } });
264
+ args: [{ selector: 'wr-calendar-heatmap', encapsulation: ViewEncapsulation.None, host: { class: 'wr-calendar-heatmap' }, template: "<div\n class=\"wr-calendar-heatmap__grid\"\n role=\"img\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\n [style.--wr-heatmap-cell-size.px]=\"cellSize()\"\n [style.--wr-heatmap-cell-gap.px]=\"cellGap()\"\n [style.--wr-heatmap-columns]=\"columnCount()\"\n>\n @if (showLabels()) {\n <div class=\"wr-calendar-heatmap__weekdays\">\n @for (label of weekdayLabels(); track $index) {\n <span class=\"wr-calendar-heatmap__weekday\">{{ label }}</span>\n }\n </div>\n }\n\n <div #days class=\"wr-calendar-heatmap__cells\" (mousemove)=\"onCellsPointer($event)\" (mouseleave)=\"tip.leave($event)\">\n @for (cell of cells(); track cell.iso) {\n <span\n class=\"wr-calendar-heatmap__cell\"\n [style.background]=\"colorFor(cell.intensity)\"\n [style.opacity]=\"opacityFor(cell.intensity)\"\n [style.grid-column]=\"cell.week + 1\"\n [style.grid-row]=\"cell.day + 1\"\n [attr.title]=\"tooltip() ? null : cellTitle(cell)\"\n [attr.data-date]=\"cell.iso\"\n [attr.data-value]=\"cell.value\"\n aria-hidden=\"true\"\n ></span>\n }\n </div>\n\n @if (showLabels()) {\n <div class=\"wr-calendar-heatmap__months\">\n @for (m of monthLabels(); track $index) {\n <span class=\"wr-calendar-heatmap__month\" [style.grid-column]=\"m.week + 1\">{{ m.label }}</span>\n }\n </div>\n }\n</div>\n" }]
265
+ }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], endDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "endDate", required: false }] }], weeks: [{ type: i0.Input, args: [{ isSignal: true, alias: "weeks", required: false }] }], cellSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellSize", required: false }] }], cellGap: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellGap", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], emptyColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyColor", required: false }] }], showLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLabels", required: false }] }], tooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltip", required: false }] }], daysEl: [{ type: i0.ViewChild, args: ['days', { isSignal: true }] }] } });
211
266
 
212
267
  /**
213
268
  * Generated bundle index. Do not edit.
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-calendar-heatmap.mjs","sources":["../../../projects/lib/calendar-heatmap/calendar-heatmap.ts","../../../projects/lib/calendar-heatmap/calendar-heatmap.html","../../../projects/lib/calendar-heatmap/ngwr-calendar-heatmap.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';\nimport { Component, ViewEncapsulation, computed, inject, input } from '@angular/core';\n\nimport { WR_DATE_LOCALE } from 'ngwr/date';\nimport { useI18nFormatter, useI18nText } from 'ngwr/i18n';\n\nimport type { WrHeatmapDatum } from './interfaces';\n\ninterface Cell {\n readonly iso: string;\n /** The day as the reader's locale writes it — see `cellTitle`. */\n readonly date: Date;\n readonly value: number;\n readonly intensity: number;\n readonly week: number;\n readonly day: number;\n}\n\nfunction toIso(d: Date): string {\n const y = d.getFullYear();\n const m = String(d.getMonth() + 1).padStart(2, '0');\n const day = String(d.getDate()).padStart(2, '0');\n return `${y}-${m}-${day}`;\n}\n\nfunction parseInput(value: string | Date): Date {\n return value instanceof Date ? new Date(value) : new Date(`${value}T00:00:00`);\n}\n\n/** Which rows carry a weekday label: three of seven, or they do not fit. */\nconst LABELLED_ROWS = new Set([1, 3, 5]);\n\n/**\n * A day's contribution, with anything non-finite read as `0`.\n *\n * One `NaN` used to flatten the entire rendered window rather than its own day:\n * `Math.max(a, NaN)` is `NaN`, so the data set's maximum became `NaN`, `max > 0`\n * was false, and every cell fell to intensity 0 — a map that reads as a stretch\n * with no activity at all. The bad day also printed the literal text `NaN` in its\n * `title`.\n */\nfunction amount(raw: number): number {\n return Number.isFinite(raw) ? raw : 0;\n}\n\n/**\n * GitHub-style year-grid heatmap. One column per ISO week, one row per\n * weekday — cells coloured by `value` relative to the data set's max.\n *\n * @example\n * ```html\n * <wr-calendar-heatmap [data]=\"contributions\" />\n * <wr-calendar-heatmap [data]=\"data\" [endDate]=\"today\" [weeks]=\"26\" color=\"#10b981\" />\n * ```\n *\n * @see https://ngwr.dev/reference/components/calendar-heatmap\n */\n@Component({\n selector: 'wr-calendar-heatmap',\n templateUrl: './calendar-heatmap.html',\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-calendar-heatmap' },\n})\nexport class WrCalendarHeatmap {\n readonly data = input<readonly WrHeatmapDatum[]>([]);\n\n /**\n * Accessible name of the whole grid. Its cells are bare spans whose `title` a screen\n * reader on a role-less element does not read, so the map used to be several hundred\n * anonymous nodes with no name. Falls back to `calendarHeatmap.label`.\n */\n readonly ariaLabel = input<string | null>(null);\n\n protected readonly resolvedAriaLabel = useI18nText(this.ariaLabel, 'calendarHeatmap.label', 'Calendar heatmap');\n\n private readonly cellText = useI18nFormatter('calendarHeatmap.cell', '{{date}}: {{count}}');\n\n /**\n * A cell's tooltip, with both halves formatted and the sentence in the catalog.\n *\n * It used to be `` `${cell.iso}: ${cell.value}` `` — a raw ISO date beside an\n * unformatted number, joined by a hard-coded `': '`. Three things were wrong\n * at once and none of them are visible from the template: `2026-09-10` is not\n * how most of the world writes a date, `1234` is not how every locale groups\n * digits (`ar-SA` does not even use these ones), and the separator and order\n * were frozen into a shape a translator could not reach.\n *\n * Both halves go through `Intl` on the SAME locale the rest of the component\n * resolves — `WR_DATE_LOCALE`, which since v14 follows Angular's `LOCALE_ID`.\n * The key ships as `{{date}}: {{count}}` everywhere, so nothing reorders today\n * and every locale can.\n */\n protected cellTitle(cell: { readonly date: Date; readonly value: number }): string {\n return this.cellText({\n date: new Intl.DateTimeFormat(this.locale, { dateStyle: 'medium' }).format(cell.date),\n count: new Intl.NumberFormat(this.locale).format(cell.value),\n });\n }\n\n /** Last day to render. @default today */\n readonly endDate = input<string | Date | null>(null);\n\n /** Number of weeks (columns) to render. @default 53 */\n readonly weeks = input(53, { transform: (v: unknown): number => Math.max(4, coerceNumberProperty(v, 53)) });\n\n /** Cell side in CSS pixels. @default 11 */\n readonly cellSize = input(11, { transform: (v: unknown): number => Math.max(4, coerceNumberProperty(v, 11)) });\n\n /** Pixel gap between cells. @default 2 */\n readonly cellGap = input(2, { transform: (v: unknown): number => Math.max(0, coerceNumberProperty(v, 2)) });\n\n /** Cell fill colour at full intensity. @default primary */\n readonly color = input<string>('var(--wr-color-primary)');\n\n /** Background colour for zero-value days. @default light tint */\n readonly emptyColor = input<string>('rgba(var(--wr-color-light-rgb), 0.5)');\n\n /** Show the weekday + month labels around the grid. @default true */\n readonly showLabels = input(true, { transform: coerceBooleanProperty });\n\n private readonly locale = inject(WR_DATE_LOCALE);\n\n /**\n * Weekday names from the locale rather than a hard-coded English list — the row order is\n * Sunday-first, matching the grid's own alignment, so 7 Jan 2024 (a Sunday) is the\n * reference. Rows without a label stay blank on purpose: seven labels do not fit.\n */\n protected readonly weekdayLabels = computed<readonly string[]>(() => {\n const formatter = new Intl.DateTimeFormat(this.locale, { weekday: 'short' });\n const sunday = new Date(2024, 0, 7);\n return Array.from({ length: 7 }, (_, row) => {\n if (!LABELLED_ROWS.has(row)) return '';\n const day = new Date(sunday);\n day.setDate(sunday.getDate() + row);\n return formatter.format(day);\n });\n });\n\n private readonly monthNames = computed<readonly string[]>(() => {\n const formatter = new Intl.DateTimeFormat(this.locale, { month: 'short' });\n return Array.from({ length: 12 }, (_, month) => formatter.format(new Date(2024, month, 15)));\n });\n\n protected readonly cells = computed<readonly Cell[]>(() => {\n const end = this.endDate() ? parseInput(this.endDate()!) : new Date();\n end.setHours(0, 0, 0, 0);\n const weeks = this.weeks();\n const totalDays = weeks * 7;\n\n // Build value lookup.\n const map = new Map<string, number>();\n for (const d of this.data()) {\n const iso = toIso(parseInput(d.date));\n map.set(iso, (map.get(iso) ?? 0) + amount(d.value));\n }\n const max = [...map.values()].reduce((a, b) => Math.max(a, b), 0);\n\n // Walk backwards from end day; arrange into columns by week, rows by weekday.\n const out: Cell[] = [];\n const start = new Date(end);\n start.setDate(end.getDate() - totalDays + 1);\n // Align start so column 0 begins on a Sunday (matches GitHub).\n start.setDate(start.getDate() - start.getDay());\n\n const cursor = new Date(start);\n let column = 0;\n while (cursor <= end) {\n for (let row = 0; row < 7; row++) {\n const iso = toIso(cursor);\n const value = map.get(iso) ?? 0;\n // Clamped at the BOTTOM as well as the top. A negative value produced a\n // negative intensity, which is not zero — so `colorFor` painted it in\n // the accent colour and `opacityFor` put it in the lightest band,\n // rendering a day of negative activity exactly like a day of light\n // activity, and unlike the empty day it should have matched. The scale\n // has no negative half; the honest floor is \"nothing\".\n const intensity = max > 0 ? Math.min(1, Math.max(0, value / max)) : 0;\n out.push({ iso, date: new Date(cursor), value, intensity, week: column, day: row });\n cursor.setDate(cursor.getDate() + 1);\n }\n column++;\n }\n return out;\n });\n\n protected readonly monthLabels = computed(() => {\n // Pull the first cell of each visible month → render a label centered\n // over its column.\n const cells = this.cells();\n const seen = new Set<string>();\n return cells\n .filter(cell => {\n const date = new Date(`${cell.iso}T00:00:00`);\n if (date.getDate() !== 1) return false;\n const key = `${date.getFullYear()}-${date.getMonth()}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n })\n .map(cell => ({\n label: this.monthNames()[new Date(`${cell.iso}T00:00:00`).getMonth()],\n week: cell.week,\n }));\n });\n\n protected readonly columnCount = computed(() => {\n const cells = this.cells();\n return cells.length === 0 ? 0 : cells[cells.length - 1].week + 1;\n });\n\n protected colorFor(intensity: number): string {\n if (intensity === 0) return this.emptyColor();\n return this.color();\n }\n\n protected opacityFor(intensity: number): number {\n if (intensity === 0) return 1;\n // 4 levels — match the GitHub aesthetic.\n if (intensity < 0.25) return 0.25;\n if (intensity < 0.5) return 0.5;\n if (intensity < 0.75) return 0.75;\n return 1;\n }\n}\n\nexport type { WrHeatmapDatum } from './interfaces';\n","<div\n class=\"wr-calendar-heatmap__grid\"\n role=\"img\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\n [style.--wr-heatmap-cell-size.px]=\"cellSize()\"\n [style.--wr-heatmap-cell-gap.px]=\"cellGap()\"\n [style.--wr-heatmap-columns]=\"columnCount()\"\n>\n @if (showLabels()) {\n <div class=\"wr-calendar-heatmap__weekdays\">\n @for (label of weekdayLabels(); track $index) {\n <span class=\"wr-calendar-heatmap__weekday\">{{ label }}</span>\n }\n </div>\n }\n\n <div class=\"wr-calendar-heatmap__cells\">\n @for (cell of cells(); track cell.iso) {\n <span\n class=\"wr-calendar-heatmap__cell\"\n [style.background]=\"colorFor(cell.intensity)\"\n [style.opacity]=\"opacityFor(cell.intensity)\"\n [style.grid-column]=\"cell.week + 1\"\n [style.grid-row]=\"cell.day + 1\"\n [title]=\"cellTitle(cell)\"\n [attr.data-date]=\"cell.iso\"\n [attr.data-value]=\"cell.value\"\n aria-hidden=\"true\"\n ></span>\n }\n </div>\n\n @if (showLabels()) {\n <div class=\"wr-calendar-heatmap__months\">\n @for (m of monthLabels(); track $index) {\n <span class=\"wr-calendar-heatmap__month\" [style.grid-column]=\"m.week + 1\">{{ m.label }}</span>\n }\n </div>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngwr-calendar-heatmap.mjs","sources":["../../../projects/lib/calendar-heatmap/calendar-heatmap.ts","../../../projects/lib/calendar-heatmap/calendar-heatmap.html","../../../projects/lib/calendar-heatmap/ngwr-calendar-heatmap.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';\nimport { Component, type ElementRef, ViewEncapsulation, computed, inject, input, viewChild } from '@angular/core';\n\nimport { WR_DATE_LOCALE } from 'ngwr/date';\nimport { useI18nFormatter, useI18nText } from 'ngwr/i18n';\nimport { useChartTooltip } from 'ngwr/popover';\n\nimport type { WrHeatmapDatum } from './interfaces';\n\ninterface Cell {\n readonly iso: string;\n /** The day as the reader's locale writes it — see `cellTitle`. */\n readonly date: Date;\n readonly value: number;\n readonly intensity: number;\n readonly week: number;\n readonly day: number;\n}\n\nfunction toIso(d: Date): string {\n const y = d.getFullYear();\n const m = String(d.getMonth() + 1).padStart(2, '0');\n const day = String(d.getDate()).padStart(2, '0');\n return `${y}-${m}-${day}`;\n}\n\nfunction parseInput(value: string | Date): Date {\n return value instanceof Date ? new Date(value) : new Date(`${value}T00:00:00`);\n}\n\n/** Which rows carry a weekday label: three of seven, or they do not fit. */\nconst LABELLED_ROWS = new Set([1, 3, 5]);\n\n/**\n * A day's contribution, with anything non-finite read as `0`.\n *\n * One `NaN` used to flatten the entire rendered window rather than its own day:\n * `Math.max(a, NaN)` is `NaN`, so the data set's maximum became `NaN`, `max > 0`\n * was false, and every cell fell to intensity 0 — a map that reads as a stretch\n * with no activity at all. The bad day also printed the literal text `NaN` in its\n * `title`.\n */\nfunction amount(raw: number): number {\n return Number.isFinite(raw) ? raw : 0;\n}\n\n/**\n * GitHub-style year-grid heatmap. One column per ISO week, one row per\n * weekday — cells coloured by `value` relative to the data set's max.\n *\n * @example\n * ```html\n * <wr-calendar-heatmap [data]=\"contributions\" />\n * <wr-calendar-heatmap [data]=\"data\" [endDate]=\"today\" [weeks]=\"26\" color=\"#10b981\" />\n * ```\n *\n * @see https://ngwr.dev/reference/components/calendar-heatmap\n */\n@Component({\n selector: 'wr-calendar-heatmap',\n templateUrl: './calendar-heatmap.html',\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-calendar-heatmap' },\n})\nexport class WrCalendarHeatmap {\n readonly data = input<readonly WrHeatmapDatum[]>([]);\n\n /**\n * Accessible name of the whole grid. Its cells are bare spans whose `title` a screen\n * reader on a role-less element does not read, so the map used to be several hundred\n * anonymous nodes with no name. Falls back to `calendarHeatmap.label`.\n */\n readonly ariaLabel = input<string | null>(null);\n\n protected readonly resolvedAriaLabel = useI18nText(this.ariaLabel, 'calendarHeatmap.label', 'Calendar heatmap');\n\n private readonly cellText = useI18nFormatter('calendarHeatmap.cell', '{{date}}: {{count}}');\n\n /**\n * A cell's tooltip, with both halves formatted and the sentence in the catalog.\n *\n * It used to be `` `${cell.iso}: ${cell.value}` `` — a raw ISO date beside an\n * unformatted number, joined by a hard-coded `': '`. Three things were wrong\n * at once and none of them are visible from the template: `2026-09-10` is not\n * how most of the world writes a date, `1234` is not how every locale groups\n * digits (`ar-SA` does not even use these ones), and the separator and order\n * were frozen into a shape a translator could not reach.\n *\n * Both halves go through `Intl` on the SAME locale the rest of the component\n * resolves — `WR_DATE_LOCALE`, which since v14 follows Angular's `LOCALE_ID`.\n * The key ships as `{{date}}: {{count}}` everywhere, so nothing reorders today\n * and every locale can.\n */\n protected cellTitle(cell: { readonly date: Date; readonly value: number }): string {\n return this.cellText({\n date: new Intl.DateTimeFormat(this.locale, { dateStyle: 'medium' }).format(cell.date),\n count: new Intl.NumberFormat(this.locale).format(cell.value),\n });\n }\n\n /** Last day to render. @default today */\n readonly endDate = input<string | Date | null>(null);\n\n /** Number of weeks (columns) to render. @default 53 */\n readonly weeks = input(53, { transform: (v: unknown): number => Math.max(4, coerceNumberProperty(v, 53)) });\n\n /** Cell side in CSS pixels. @default 11 */\n readonly cellSize = input(11, { transform: (v: unknown): number => Math.max(4, coerceNumberProperty(v, 11)) });\n\n /** Pixel gap between cells. @default 2 */\n readonly cellGap = input(2, { transform: (v: unknown): number => Math.max(0, coerceNumberProperty(v, 2)) });\n\n /** Cell fill colour at full intensity. @default primary */\n readonly color = input<string>('var(--wr-color-primary)');\n\n /** Background colour for zero-value days. @default light tint */\n readonly emptyColor = input<string>('rgba(var(--wr-color-light-rgb), 0.5)');\n\n /** Show the weekday + month labels around the grid. @default true */\n readonly showLabels = input(true, { transform: coerceBooleanProperty });\n\n /**\n * Show a tooltip with the day and its count on hover. It is the sentence the\n * square's `title` carried, so the `title` is written only while this is off —\n * or the browser would open a second copy a moment later. @default true\n */\n readonly tooltip = input(true, { transform: coerceBooleanProperty });\n\n private readonly daysEl = viewChild<ElementRef<HTMLElement>>('days');\n\n private readonly locale = inject(WR_DATE_LOCALE);\n\n /**\n * Weekday names from the locale rather than a hard-coded English list — the row order is\n * Sunday-first, matching the grid's own alignment, so 7 Jan 2024 (a Sunday) is the\n * reference. Rows without a label stay blank on purpose: seven labels do not fit.\n */\n protected readonly weekdayLabels = computed<readonly string[]>(() => {\n const formatter = new Intl.DateTimeFormat(this.locale, { weekday: 'short' });\n const sunday = new Date(2024, 0, 7);\n return Array.from({ length: 7 }, (_, row) => {\n if (!LABELLED_ROWS.has(row)) return '';\n const day = new Date(sunday);\n day.setDate(sunday.getDate() + row);\n return formatter.format(day);\n });\n });\n\n private readonly monthNames = computed<readonly string[]>(() => {\n const formatter = new Intl.DateTimeFormat(this.locale, { month: 'short' });\n return Array.from({ length: 12 }, (_, month) => formatter.format(new Date(2024, month, 15)));\n });\n\n protected readonly cells = computed<readonly Cell[]>(() => {\n const end = this.endDate() ? parseInput(this.endDate()!) : new Date();\n end.setHours(0, 0, 0, 0);\n const weeks = this.weeks();\n const totalDays = weeks * 7;\n\n // Build value lookup.\n const map = new Map<string, number>();\n for (const d of this.data()) {\n const iso = toIso(parseInput(d.date));\n map.set(iso, (map.get(iso) ?? 0) + amount(d.value));\n }\n const max = [...map.values()].reduce((a, b) => Math.max(a, b), 0);\n\n // Walk backwards from end day; arrange into columns by week, rows by weekday.\n const out: Cell[] = [];\n const start = new Date(end);\n start.setDate(end.getDate() - totalDays + 1);\n // Align start so column 0 begins on a Sunday (matches GitHub).\n start.setDate(start.getDate() - start.getDay());\n\n const cursor = new Date(start);\n let column = 0;\n while (cursor <= end) {\n for (let row = 0; row < 7; row++) {\n const iso = toIso(cursor);\n const value = map.get(iso) ?? 0;\n // Clamped at the BOTTOM as well as the top. A negative value produced a\n // negative intensity, which is not zero — so `colorFor` painted it in\n // the accent colour and `opacityFor` put it in the lightest band,\n // rendering a day of negative activity exactly like a day of light\n // activity, and unlike the empty day it should have matched. The scale\n // has no negative half; the honest floor is \"nothing\".\n const intensity = max > 0 ? Math.min(1, Math.max(0, value / max)) : 0;\n out.push({ iso, date: new Date(cursor), value, intensity, week: column, day: row });\n cursor.setDate(cursor.getDate() + 1);\n }\n column++;\n }\n return out;\n });\n\n protected readonly monthLabels = computed(() => {\n // Pull the first cell of each visible month → render a label centered\n // over its column.\n const cells = this.cells();\n const seen = new Set<string>();\n return cells\n .filter(cell => {\n const date = new Date(`${cell.iso}T00:00:00`);\n if (date.getDate() !== 1) return false;\n const key = `${date.getFullYear()}-${date.getMonth()}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n })\n .map(cell => ({\n label: this.monthNames()[new Date(`${cell.iso}T00:00:00`).getMonth()],\n week: cell.week,\n }));\n });\n\n protected readonly columnCount = computed(() => {\n const cells = this.cells();\n return cells.length === 0 ? 0 : cells[cells.length - 1].week + 1;\n });\n\n /** Each day's position in `cells()`, for the square the pointer lands on. */\n private readonly indexByIso = computed(() => new Map(this.cells().map((cell, index) => [cell.iso, index])));\n\n /**\n * One tooltip for the whole year, pointing at the hovered day: above its square,\n * below it when there is no room above, and slid along the viewport edge for the\n * first and last weeks with the arrow still on the square. A listener on the grid\n * rather than one per square: a year is 371 of them.\n *\n * The box is the square's LAYOUT box rather than its client rect. The hovered square\n * grows by `:hover` over a transition, and a rect read part way through it would\n * move the chip by up to a fifth of a square depending on when it was measured;\n * the scale is centred, so the layout box is the rect's centre and the square's\n * own size.\n */\n protected readonly tip = useChartTooltip(this.tooltip, index => {\n const cell = this.cells()[index];\n // The squares are the container's only children, drawn in `cells()` order.\n const square = cell ? this.daysEl()?.nativeElement.children.item(index) : null;\n if (!cell || !(square instanceof HTMLElement)) return null;\n const rect = square.getBoundingClientRect();\n const width = square.offsetWidth;\n const height = square.offsetHeight;\n return {\n datum: { value: this.cellTitle(cell) },\n anchor: {\n x: (rect.left + rect.right - width) / 2,\n y: (rect.top + rect.bottom - height) / 2,\n width,\n height,\n },\n };\n });\n\n /**\n * Which square the pointer is on, from a `mousemove` on the grid. Over the gap\n * between two squares it is on none, and the tooltip starts to leave.\n */\n protected onCellsPointer(event: MouseEvent): void {\n const iso = (event.target as Element | null)?.closest<HTMLElement>('.wr-calendar-heatmap__cell')?.dataset['date'];\n const index = iso === undefined ? undefined : this.indexByIso().get(iso);\n if (index === undefined) this.tip.leave(event);\n else this.tip.enter(index);\n }\n\n protected colorFor(intensity: number): string {\n if (intensity === 0) return this.emptyColor();\n return this.color();\n }\n\n protected opacityFor(intensity: number): number {\n if (intensity === 0) return 1;\n // 4 levels — match the GitHub aesthetic.\n if (intensity < 0.25) return 0.25;\n if (intensity < 0.5) return 0.5;\n if (intensity < 0.75) return 0.75;\n return 1;\n }\n}\n\nexport type { WrHeatmapDatum } from './interfaces';\n","<div\n class=\"wr-calendar-heatmap__grid\"\n role=\"img\"\n [attr.aria-label]=\"resolvedAriaLabel()\"\n [style.--wr-heatmap-cell-size.px]=\"cellSize()\"\n [style.--wr-heatmap-cell-gap.px]=\"cellGap()\"\n [style.--wr-heatmap-columns]=\"columnCount()\"\n>\n @if (showLabels()) {\n <div class=\"wr-calendar-heatmap__weekdays\">\n @for (label of weekdayLabels(); track $index) {\n <span class=\"wr-calendar-heatmap__weekday\">{{ label }}</span>\n }\n </div>\n }\n\n <div #days class=\"wr-calendar-heatmap__cells\" (mousemove)=\"onCellsPointer($event)\" (mouseleave)=\"tip.leave($event)\">\n @for (cell of cells(); track cell.iso) {\n <span\n class=\"wr-calendar-heatmap__cell\"\n [style.background]=\"colorFor(cell.intensity)\"\n [style.opacity]=\"opacityFor(cell.intensity)\"\n [style.grid-column]=\"cell.week + 1\"\n [style.grid-row]=\"cell.day + 1\"\n [attr.title]=\"tooltip() ? null : cellTitle(cell)\"\n [attr.data-date]=\"cell.iso\"\n [attr.data-value]=\"cell.value\"\n aria-hidden=\"true\"\n ></span>\n }\n </div>\n\n @if (showLabels()) {\n <div class=\"wr-calendar-heatmap__months\">\n @for (m of monthLabels(); track $index) {\n <span class=\"wr-calendar-heatmap__month\" [style.grid-column]=\"m.week + 1\">{{ m.label }}</span>\n }\n </div>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-calendar-testing.mjs","sources":["../../../projects/lib/calendar/testing/wr-calendar-day-harness.ts","../../../projects/lib/calendar/testing/wr-calendar-harness.ts","../../../projects/lib/calendar/testing/ngwr-calendar-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 type { WrCalendarDayHarnessFilters } from './interfaces';\n\n/**\n * Test harness for one day cell of a `<wr-calendar>` grid.\n *\n * The cell belongs to the calendar, and a date-picker's popup is a calendar in an\n * overlay — so this is the harness for both, re-exported from\n * `ngwr/date-picker/testing` under the name it shipped as\n * (`WrDatePickerDayHarness`). Reach it through `WrCalendarHarness.getDays()`, or\n * through `WrDatePickerHarness.getDay()` / `getDays()`, which scope it to ONE\n * picker's panel — those cells are in the shared overlay container, so a bare query\n * would answer with whichever picker opened first.\n *\n * State is read the way a screen reader reads it (`role`, `aria-selected`,\n * `aria-disabled`) with the `.wr-calendar__day--*` modifiers filling in what\n * ARIA has no word for: today, the spill days of the neighbouring months, and\n * the interior of a picked range.\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrCalendarDayHarness extends ComponentHarness {\n static hostSelector = '.wr-calendar__day';\n\n /** Build a predicate that narrows the query. */\n static with(options: WrCalendarDayHarnessFilters = {}): HarnessPredicate<WrCalendarDayHarness> {\n return new HarnessPredicate(WrCalendarDayHarness, options)\n .addOption('text', options.text, (harness, text) => HarnessPredicate.stringMatches(harness.getText(), text))\n .addOption('selected', options.selected, async (harness, selected) => (await harness.isSelected()) === selected)\n .addOption('disabled', options.disabled, async (harness, disabled) => (await harness.isDisabled()) === disabled)\n .addOption('inRange', options.inRange, async (harness, inRange) => (await harness.isInRange()) === inRange);\n }\n\n /** The day number as rendered. */\n async getText(): Promise<string> {\n return (await this.host()).text();\n }\n\n /** The day number as a number, for mapping a list of cells to dates. */\n async getDayOfMonth(): Promise<number> {\n return Number(await this.getText());\n }\n\n /**\n * What a screen reader announces for this cell — \"Thursday, January 15, 2026\".\n *\n * A SECOND question from {@link getText}, and the reason this method exists:\n * until v14 the cell had no name at all, so the two answers were \"15\" and\n * nothing. A spec that reads only the drawn number passes on a grid that\n * announces bare integers with no month, year or weekday anywhere in it.\n *\n * The string is `calendar.dayLabel` interpolated with the adapter's\n * `longDate`, so it moves with the locale AND with the adapter — assert\n * against the pair your spec provides, not against an English literal.\n */\n async getAccessibleName(): Promise<string | null> {\n return (await this.host()).getAttribute('aria-label');\n }\n\n /** `'gridcell'` — the cell is a button, and the grid semantics are what a spec should assert. */\n async getRole(): Promise<string | null> {\n return (await this.host()).getAttribute('role');\n }\n\n /** Whether this day is (one end of) the current selection. */\n async isSelected(): Promise<boolean> {\n return (await (await this.host()).getAttribute('aria-selected')) === 'true';\n }\n\n /**\n * Whether the day refuses selection — `min` / `max` or `dateFilter` ruled it\n * out, or the whole calendar is disabled.\n */\n async isDisabled(): Promise<boolean> {\n return (await (await this.host()).getAttribute('aria-disabled')) === 'true';\n }\n\n /** Whether the cell is today's date. */\n async isToday(): Promise<boolean> {\n return (await this.host()).hasClass('wr-calendar__day--today');\n }\n\n /**\n * Whether the cell belongs to a neighbouring month. The grid is always 6x7, so\n * every month is padded with days that are selectable but not \"in\" the month —\n * which is why `WrDatePickerHarness.getDay` and {@link WrCalendarHarness.getDay} skip them.\n */\n async isOutOfMonth(): Promise<boolean> {\n return (await this.host()).hasClass('wr-calendar__day--out-of-month');\n }\n\n /** Whether the day lies strictly between the two ends of a picked range. */\n async isInRange(): Promise<boolean> {\n return (await this.host()).hasClass('wr-calendar__day--in-range');\n }\n\n /**\n * Whether this is the roving cell — the grid's single tab stop, and where the\n * arrow keys move from.\n *\n * At most ONE cell answers `true`, and it is not always one: the calendar's\n * roving date does not follow `next()` / `previous()`, so a grid navigated away\n * from that month has no active cell (and, deliberately or not, no tab stop)\n * until a cell is clicked or the arrows move it.\n */\n async isActive(): Promise<boolean> {\n return (await this.host()).hasClass('wr-calendar__day--focused');\n }\n\n /** Click the cell. A disabled cell swallows the click — assert, do not assume. */\n async click(): Promise<void> {\n return (await this.host()).click();\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ComponentHarness, HarnessPredicate, TestKey, type TestElement } from '@angular/cdk/testing';\n\nimport type { WrCalendarMode } from 'ngwr/calendar';\n\nimport type {\n WrCalendarArrowKey,\n WrCalendarChip,\n WrCalendarDayHarnessFilters,\n WrCalendarHarnessFilters,\n WrCalendarView,\n} from './interfaces';\nimport { WrCalendarDayHarness } from './wr-calendar-day-harness';\n\nconst ARROWS: Record<WrCalendarArrowKey, TestKey> = {\n left: TestKey.LEFT_ARROW,\n right: TestKey.RIGHT_ARROW,\n up: TestKey.UP_ARROW,\n down: TestKey.DOWN_ARROW,\n};\n\n/**\n * Test harness for `<wr-calendar>` — the standalone month grid, and the one\n * `<wr-date-picker>` puts in an overlay.\n *\n * **It is three views behind one header.** Clicking the header label walks\n * `day → month → year`, and each view renders something different: a\n * `role=\"grid\"` of day cells, or a `role=\"listbox\"` of chips. Every day method\n * throws off the day view rather than answering `[]`, which would read as \"this\n * month has no days\".\n *\n * **The roving cell is not the selection.** The grid has one tab stop and the\n * arrows move it; it starts on the selected date, or on today when nothing is\n * picked. And it does NOT follow {@link next} / {@link previous} — a grid paged\n * away from the roving month has no active cell at all, and so no tab stop, until\n * a key or a click puts one back. That is the component's behaviour, and\n * {@link getActiveDayNumber} is how a spec sees it.\n *\n * **Keys go to the host, not to a cell.** The component listens on its own element,\n * so {@link pressArrow} works whether or not jsdom managed to put real focus\n * anywhere — which it often does not, since the calendar moves focus in an\n * `afterNextRender` and a disabled cell cannot take it.\n *\n * @example\n * ```ts\n * const calendar = await loader.getHarness(WrCalendarHarness);\n *\n * expect(await calendar.getHeaderLabel()).toBe('March 2026');\n * await (await calendar.getDay(14)).click();\n * expect(await calendar.getSelectedDayNumbers()).toEqual([14]);\n * ```\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrCalendarHarness extends ComponentHarness {\n static hostSelector = 'wr-calendar';\n\n /** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */\n static with(options: WrCalendarHarnessFilters = {}): HarnessPredicate<WrCalendarHarness> {\n return new HarnessPredicate(WrCalendarHarness, options)\n .addOption('headerLabel', options.headerLabel, (harness, label) =>\n HarnessPredicate.stringMatches(harness.getHeaderLabel(), label)\n )\n .addOption('mode', options.mode, async (harness, mode) => (await harness.getMode()) === mode)\n .addOption('disabled', options.disabled, async (harness, disabled) => (await harness.isDisabled()) === disabled);\n }\n\n private readonly header = this.locatorFor('.wr-calendar__label');\n private readonly prevButton = this.locatorFor('.wr-calendar__nav--prev');\n private readonly nextButton = this.locatorFor('.wr-calendar__nav--next');\n\n /** Which sub-view is showing. */\n async getView(): Promise<WrCalendarView> {\n if ((await this.locatorForOptional('.wr-calendar__months')()) !== null) return 'month';\n if ((await this.locatorForOptional('.wr-calendar__years')()) !== null) return 'year';\n return 'day';\n }\n\n /** Single- or range-selection, from the host modifier. */\n async getMode(): Promise<WrCalendarMode> {\n return (await (await this.host()).hasClass('wr-calendar--range')) ? 'range' : 'single';\n }\n\n /** Whether the whole calendar refuses interaction. */\n async isDisabled(): Promise<boolean> {\n return (await this.host()).hasClass('wr-calendar--disabled');\n }\n\n /** The header text — `March 2026`, `2026`, or `2016 – 2027` depending on the view. */\n async getHeaderLabel(): Promise<string> {\n return (await this.header()).text();\n }\n\n /**\n * Click the header — stepping `day → month → year`.\n *\n * The year view is the end of the walk: the header is disabled there, so this\n * throws rather than clicking a button the DOM would ignore.\n */\n async clickHeader(): Promise<void> {\n const header = await this.header();\n if (await header.getProperty<boolean>('disabled')) {\n throw new Error(\n `WrCalendarHarness.clickHeader(): the header is disabled — the calendar is on the ` +\n `${await this.getView()} view, which is where the walk stops (or the whole calendar is disabled).`\n );\n }\n await header.click();\n }\n\n /**\n * Step back — a month, a year or twelve years, depending on the view.\n *\n * The roving day cell does NOT come along: paging is a view change, not a\n * navigation, and the tab stop stays on the month it was in.\n */\n async previous(): Promise<void> {\n await (await this.prevButton()).click();\n }\n\n /** Step forward — a month, a year or twelve years, depending on the view. */\n async next(): Promise<void> {\n await (await this.nextButton()).click();\n }\n\n /**\n * The back arrow's accessible name, which changes with the view — the arrows are\n * icon-only, so this is the only name they have.\n */\n async getPreviousLabel(): Promise<string | null> {\n return (await this.prevButton()).getAttribute('aria-label');\n }\n\n /** The forward arrow's accessible name. */\n async getNextLabel(): Promise<string | null> {\n return (await this.nextButton()).getAttribute('aria-label');\n }\n\n /** The weekday column headers, in the order the adapter's first day of week puts them. */\n async getWeekdayNames(): Promise<string[]> {\n await this.requireView('day', 'getWeekdayNames');\n const names = await this.locatorForAll('.wr-calendar__weekday')();\n return Promise.all(names.map(name => name.text()));\n }\n\n /**\n * Every day cell, in DOM order — 42 of them, since the grid is always six weeks.\n *\n * That includes the spill days of the neighbouring months, which are selectable\n * and not \"in\" the month; {@link getDay} skips them, and\n * `WrCalendarDayHarness.isOutOfMonth()` tells them apart.\n */\n async getDays(filters: WrCalendarDayHarnessFilters = {}): Promise<WrCalendarDayHarness[]> {\n await this.requireView('day', 'getDays');\n return this.locatorForAll(WrCalendarDayHarness.with(filters))();\n }\n\n /**\n * The cell for a day of THIS month.\n *\n * The number alone is ambiguous — a 42-cell grid shows most numbers twice — so\n * the spill days are skipped rather than matched, which is what \"the 3rd\" means\n * to someone reading the calendar.\n */\n async getDay(dayOfMonth: number): Promise<WrCalendarDayHarness> {\n for (const day of await this.getDays({ text: String(dayOfMonth) })) {\n if (!(await day.isOutOfMonth())) return day;\n }\n throw new Error(\n `WrCalendarHarness.getDay(${dayOfMonth}): no such day in ${await this.getHeaderLabel()}. Only cells of ` +\n 'the displayed month count — the grid spills into its neighbours, and those are skipped.'\n );\n }\n\n /** The day numbers currently selected — one in single mode, both ends in range mode. */\n async getSelectedDayNumbers(): Promise<number[]> {\n const selected = await this.getDays({ selected: true });\n return Promise.all(selected.map(day => day.getDayOfMonth()));\n }\n\n /** The day numbers strictly inside a picked range — never the ends. */\n async getInRangeDayNumbers(): Promise<number[]> {\n const inRange = await this.getDays({ inRange: true });\n return Promise.all(inRange.map(day => day.getDayOfMonth()));\n }\n\n /**\n * The day number holding the roving tab stop, or `null` when the grid has none.\n *\n * `null` is a real answer, not a failure: paging with {@link next} leaves the\n * roving date behind in another month, and the grid then has no `tabindex=\"0\"`\n * at all until a key or a click puts one back.\n */\n async getActiveDayNumber(): Promise<number | null> {\n for (const day of await this.getDays()) {\n if (await day.isActive()) return day.getDayOfMonth();\n }\n return null;\n }\n\n /** The month chips, with their state. Throws off the month view. */\n async getMonths(): Promise<WrCalendarChip[]> {\n await this.requireView('month', 'getMonths');\n return this.readChips();\n }\n\n /** The year chips, with their state. Throws off the year view. */\n async getYears(): Promise<WrCalendarChip[]> {\n await this.requireView('year', 'getYears');\n return this.readChips();\n }\n\n /**\n * Click a month or year chip by its printed label — which drops the calendar back\n * one view, the way clicking the header climbed up.\n *\n * Throws on the day view, where there are no chips, and on a label the view does\n * not offer, naming what it does.\n */\n async selectChip(label: string): Promise<void> {\n const view = await this.getView();\n if (view === 'day') {\n throw new Error(\n 'WrCalendarHarness.selectChip(): the calendar is on the day view, which has no chips. Click the ' +\n 'header first — it walks day → month → year.'\n );\n }\n\n for (const chip of await this.locatorForAll('.wr-calendar__chip')()) {\n if ((await chip.text()) === label) {\n await chip.click();\n return;\n }\n }\n\n const offered = (await this.readChips()).map(chip => chip.label);\n throw new Error(`WrCalendarHarness.selectChip(\"${label}\"): the ${view} view offers: ${offered.join(', ')}.`);\n }\n\n /**\n * Press an arrow key — one day left or right, one WEEK up or down.\n *\n * Sent to the host, where the component listens, so this does not depend on jsdom\n * having managed to focus a cell. Under `dir=\"rtl\"` the horizontal pair mirrors:\n * ArrowRight goes back a day, because the grid itself is mirrored.\n */\n async pressArrow(arrow: WrCalendarArrowKey): Promise<void> {\n await (await this.host()).sendKeys(ARROWS[arrow]);\n }\n\n /** Press Home — the first day of the roving cell's week, not of the month. */\n async pressHome(): Promise<void> {\n await (await this.host()).sendKeys(TestKey.HOME);\n }\n\n /** Press End — the last day of the roving cell's week. */\n async pressEnd(): Promise<void> {\n await (await this.host()).sendKeys(TestKey.END);\n }\n\n /** Press PageUp — a month back, or a YEAR back with `shift`. */\n async pressPageUp(options: { shift?: boolean } = {}): Promise<void> {\n const host = await this.host();\n await (options.shift ? host.sendKeys({ shift: true }, TestKey.PAGE_UP) : host.sendKeys(TestKey.PAGE_UP));\n }\n\n /** Press PageDown — a month on, or a YEAR on with `shift`. */\n async pressPageDown(options: { shift?: boolean } = {}): Promise<void> {\n const host = await this.host();\n await (options.shift ? host.sendKeys({ shift: true }, TestKey.PAGE_DOWN) : host.sendKeys(TestKey.PAGE_DOWN));\n }\n\n /** Press Enter — picking the roving day, exactly as clicking it would. */\n async pressEnter(): Promise<void> {\n await (await this.host()).sendKeys(TestKey.ENTER);\n }\n\n /**\n * The role of the element that owns the day rows.\n *\n * Worth asserting rather than assuming: the grid is NOT the host. The host also\n * holds the nav header, and a `role=\"grid\"` may only own rows — so the role sits\n * on the body, and the weekday strip is a row inside it rather than a sibling.\n */\n async getGridRole(): Promise<string | null> {\n const body = await this.locatorForOptional('.wr-calendar__body')();\n return body ? body.getAttribute('role') : null;\n }\n\n /** How many week rows the grid renders — always six, which is what keeps it from reflowing. */\n async getWeekCount(): Promise<number> {\n await this.requireView('day', 'getWeekCount');\n return (await this.locatorForAll('.wr-calendar__week')()).length;\n }\n\n private async readChips(): Promise<WrCalendarChip[]> {\n const chips = await this.locatorForAll('.wr-calendar__chip')();\n\n return Promise.all(\n chips.map(async (chip: TestElement) => ({\n label: await chip.text(),\n selected: (await chip.getAttribute('aria-selected')) === 'true',\n current: await chip.hasClass('wr-calendar__chip--current'),\n disabled: (await chip.getAttribute('aria-disabled')) === 'true',\n }))\n );\n }\n\n private async requireView(view: WrCalendarView, method: string): Promise<void> {\n const current = await this.getView();\n if (current === view) return;\n\n throw new Error(\n `WrCalendarHarness.${method}(): the calendar is showing the ${current} view, not the ${view} one — those ` +\n 'elements are not rendered at all. The header walks day → month → year; clicking a chip walks back down.'\n );\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngwr-calendar-testing.mjs","sources":["../../../projects/lib/calendar/testing/wr-calendar-day-harness.ts","../../../projects/lib/calendar/testing/wr-calendar-harness.ts","../../../projects/lib/calendar/testing/ngwr-calendar-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 type { WrCalendarDayHarnessFilters } from './interfaces';\n\n/**\n * Test harness for one day cell of a `<wr-calendar>` grid.\n *\n * The cell belongs to the calendar, and a date-picker's popup is a calendar in an\n * overlay — so this is the harness for both, re-exported from\n * `ngwr/date-picker/testing` under the name it shipped as\n * (`WrDatePickerDayHarness`). Reach it through `WrCalendarHarness.getDays()`, or\n * through `WrDatePickerHarness.getDay()` / `getDays()`, which scope it to ONE\n * picker's panel — those cells are in the shared overlay container, so a bare query\n * would answer with whichever picker opened first.\n *\n * State is read the way a screen reader reads it (`role`, `aria-selected`,\n * `aria-disabled`) with the `.wr-calendar__day--*` modifiers filling in what\n * ARIA has no word for: today, the spill days of the neighbouring months, and\n * the interior of a picked range.\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrCalendarDayHarness extends ComponentHarness {\n static hostSelector = '.wr-calendar__day';\n\n /** Build a predicate that narrows the query. */\n static with(options: WrCalendarDayHarnessFilters = {}): HarnessPredicate<WrCalendarDayHarness> {\n return new HarnessPredicate(WrCalendarDayHarness, options)\n .addOption('text', options.text, (harness, text) => HarnessPredicate.stringMatches(harness.getText(), text))\n .addOption('selected', options.selected, async (harness, selected) => (await harness.isSelected()) === selected)\n .addOption('disabled', options.disabled, async (harness, disabled) => (await harness.isDisabled()) === disabled)\n .addOption('inRange', options.inRange, async (harness, inRange) => (await harness.isInRange()) === inRange);\n }\n\n /** The day number as rendered. */\n async getText(): Promise<string> {\n return (await this.host()).text();\n }\n\n /** The day number as a number, for mapping a list of cells to dates. */\n async getDayOfMonth(): Promise<number> {\n return Number(await this.getText());\n }\n\n /**\n * What a screen reader announces for this cell — \"Thursday, January 15, 2026\".\n *\n * A SECOND question from {@link getText}, and the reason this method exists:\n * until v14 the cell had no name at all, so the two answers were \"15\" and\n * nothing. A spec that reads only the drawn number passes on a grid that\n * announces bare integers with no month, year or weekday anywhere in it.\n *\n * The string is `calendar.dayLabel` interpolated with the adapter's\n * `longDate`, so it moves with the locale AND with the adapter — assert\n * against the pair your spec provides, not against an English literal.\n */\n async getAccessibleName(): Promise<string | null> {\n return (await this.host()).getAttribute('aria-label');\n }\n\n /** `'gridcell'` — the cell is a button, and the grid semantics are what a spec should assert. */\n async getRole(): Promise<string | null> {\n return (await this.host()).getAttribute('role');\n }\n\n /** Whether this day is (one end of) the current selection. */\n async isSelected(): Promise<boolean> {\n return (await (await this.host()).getAttribute('aria-selected')) === 'true';\n }\n\n /**\n * Whether the day refuses selection — `min` / `max` or `dateFilter` ruled it\n * out, or the whole calendar is disabled.\n */\n async isDisabled(): Promise<boolean> {\n return (await (await this.host()).getAttribute('aria-disabled')) === 'true';\n }\n\n /** Whether the cell is today's date. */\n async isToday(): Promise<boolean> {\n return (await this.host()).hasClass('wr-calendar__day--today');\n }\n\n /**\n * Whether the cell belongs to a neighbouring month. The grid is always 6x7, so\n * every month is padded with days that are selectable but not \"in\" the month —\n * which is why `WrDatePickerHarness.getDay` and {@link WrCalendarHarness.getDay} skip them.\n */\n async isOutOfMonth(): Promise<boolean> {\n return (await this.host()).hasClass('wr-calendar__day--out-of-month');\n }\n\n /** Whether the day lies strictly between the two ends of a picked range. */\n async isInRange(): Promise<boolean> {\n return (await this.host()).hasClass('wr-calendar__day--in-range');\n }\n\n /**\n * Whether this is the roving cell — the grid's single tab stop, and where the\n * arrow keys move from.\n *\n * At most ONE cell answers `true`, and it is not always one: the calendar's\n * roving date does not follow `next()` / `previous()`, so a grid navigated away\n * from that month has no active cell (and, deliberately or not, no tab stop)\n * until a cell is clicked or the arrows move it.\n */\n async isActive(): Promise<boolean> {\n return (await this.host()).hasClass('wr-calendar__day--focused');\n }\n\n /** Click the cell. A disabled cell swallows the click — assert, do not assume. */\n async click(): Promise<void> {\n return (await this.host()).click();\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ComponentHarness, HarnessPredicate, TestKey, type TestElement } from '@angular/cdk/testing';\n\nimport type { WrCalendarMode } from 'ngwr/calendar';\n\nimport type {\n WrCalendarArrowKey,\n WrCalendarChip,\n WrCalendarDayHarnessFilters,\n WrCalendarHarnessFilters,\n WrCalendarView,\n} from './interfaces';\nimport { WrCalendarDayHarness } from './wr-calendar-day-harness';\n\nconst ARROWS: Record<WrCalendarArrowKey, TestKey> = {\n left: TestKey.LEFT_ARROW,\n right: TestKey.RIGHT_ARROW,\n up: TestKey.UP_ARROW,\n down: TestKey.DOWN_ARROW,\n};\n\n/**\n * Test harness for `<wr-calendar>` — the standalone month grid, and the one\n * `<wr-date-picker>` puts in an overlay.\n *\n * **It is three views behind one header.** Clicking the header label walks\n * `day → month → year`, and each view renders something different: a\n * `role=\"grid\"` of day cells, or a `role=\"listbox\"` of chips. Every day method\n * throws off the day view rather than answering `[]`, which would read as \"this\n * month has no days\".\n *\n * **The roving cell is not the selection.** The grid has one tab stop and the\n * arrows move it; it starts on the selected date, or on today when nothing is\n * picked. And it does NOT follow {@link next} / {@link previous} — a grid paged\n * away from the roving month has no active cell at all, and so no tab stop, until\n * a key or a click puts one back. That is the component's behaviour, and\n * {@link getActiveDayNumber} is how a spec sees it.\n *\n * **Keys go to the host, not to a cell.** The component listens on its own element,\n * so {@link pressArrow} works whether or not jsdom managed to put real focus\n * anywhere — which it often does not, since the calendar moves focus in an\n * `afterNextRender` and a disabled cell cannot take it.\n *\n * @example\n * ```ts\n * const calendar = await loader.getHarness(WrCalendarHarness);\n *\n * expect(await calendar.getHeaderLabel()).toBe('March 2026');\n * await (await calendar.getDay(14)).click();\n * expect(await calendar.getSelectedDayNumbers()).toEqual([14]);\n * ```\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrCalendarHarness extends ComponentHarness {\n static hostSelector = 'wr-calendar';\n\n /** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */\n static with(options: WrCalendarHarnessFilters = {}): HarnessPredicate<WrCalendarHarness> {\n return new HarnessPredicate(WrCalendarHarness, options)\n .addOption('headerLabel', options.headerLabel, (harness, label) =>\n HarnessPredicate.stringMatches(harness.getHeaderLabel(), label)\n )\n .addOption('mode', options.mode, async (harness, mode) => (await harness.getMode()) === mode)\n .addOption('disabled', options.disabled, async (harness, disabled) => (await harness.isDisabled()) === disabled);\n }\n\n private readonly header = this.locatorFor('.wr-calendar__label');\n private readonly prevButton = this.locatorFor('.wr-calendar__nav--prev');\n private readonly nextButton = this.locatorFor('.wr-calendar__nav--next');\n\n /** Which sub-view is showing. */\n async getView(): Promise<WrCalendarView> {\n if ((await this.locatorForOptional('.wr-calendar__months')()) !== null) return 'month';\n if ((await this.locatorForOptional('.wr-calendar__years')()) !== null) return 'year';\n return 'day';\n }\n\n /** Single- or range-selection, from the host modifier. */\n async getMode(): Promise<WrCalendarMode> {\n return (await (await this.host()).hasClass('wr-calendar--range')) ? 'range' : 'single';\n }\n\n /** Whether the whole calendar refuses interaction. */\n async isDisabled(): Promise<boolean> {\n return (await this.host()).hasClass('wr-calendar--disabled');\n }\n\n /** The header text — `March 2026`, `2026`, or `2016 – 2027` depending on the view. */\n async getHeaderLabel(): Promise<string> {\n return (await this.header()).text();\n }\n\n /**\n * Click the header — stepping `day → month → year`.\n *\n * The year view is the end of the walk: the header is disabled there, so this\n * throws rather than clicking a button the DOM would ignore.\n */\n async clickHeader(): Promise<void> {\n const header = await this.header();\n if (await header.getProperty<boolean>('disabled')) {\n throw new Error(\n `WrCalendarHarness.clickHeader(): the header is disabled — the calendar is on the ` +\n `${await this.getView()} view, which is where the walk stops (or the whole calendar is disabled).`\n );\n }\n await header.click();\n }\n\n /**\n * Step back — a month, a year or twelve years, depending on the view.\n *\n * The roving day cell does NOT come along: paging is a view change, not a\n * navigation, and the tab stop stays on the month it was in.\n */\n async previous(): Promise<void> {\n await (await this.prevButton()).click();\n }\n\n /** Step forward — a month, a year or twelve years, depending on the view. */\n async next(): Promise<void> {\n await (await this.nextButton()).click();\n }\n\n /**\n * The back arrow's accessible name, which changes with the view — the arrows are\n * icon-only, so this is the only name they have.\n */\n async getPreviousLabel(): Promise<string | null> {\n return (await this.prevButton()).getAttribute('aria-label');\n }\n\n /** The forward arrow's accessible name. */\n async getNextLabel(): Promise<string | null> {\n return (await this.nextButton()).getAttribute('aria-label');\n }\n\n /** The weekday column headers, in the order the adapter's first day of week puts them. */\n async getWeekdayNames(): Promise<string[]> {\n await this.requireView('day', 'getWeekdayNames');\n const names = await this.locatorForAll('.wr-calendar__weekday')();\n return Promise.all(names.map(name => name.text()));\n }\n\n /**\n * Every day cell, in DOM order — 42 of them, since the grid is always six weeks.\n *\n * That includes the spill days of the neighbouring months, which are selectable\n * and not \"in\" the month; {@link getDay} skips them, and\n * `WrCalendarDayHarness.isOutOfMonth()` tells them apart.\n */\n async getDays(filters: WrCalendarDayHarnessFilters = {}): Promise<WrCalendarDayHarness[]> {\n await this.requireView('day', 'getDays');\n return this.locatorForAll(WrCalendarDayHarness.with(filters))();\n }\n\n /**\n * The cell for a day of THIS month.\n *\n * The number alone is ambiguous — a 42-cell grid shows most numbers twice — so\n * the spill days are skipped rather than matched, which is what \"the 3rd\" means\n * to someone reading the calendar.\n */\n async getDay(dayOfMonth: number): Promise<WrCalendarDayHarness> {\n for (const day of await this.getDays({ text: String(dayOfMonth) })) {\n if (!(await day.isOutOfMonth())) return day;\n }\n throw new Error(\n `WrCalendarHarness.getDay(${dayOfMonth}): no such day in ${await this.getHeaderLabel()}. Only cells of ` +\n 'the displayed month count — the grid spills into its neighbours, and those are skipped.'\n );\n }\n\n /** The day numbers currently selected — one in single mode, both ends in range mode. */\n async getSelectedDayNumbers(): Promise<number[]> {\n const selected = await this.getDays({ selected: true });\n return Promise.all(selected.map(day => day.getDayOfMonth()));\n }\n\n /** The day numbers strictly inside a picked range — never the ends. */\n async getInRangeDayNumbers(): Promise<number[]> {\n const inRange = await this.getDays({ inRange: true });\n return Promise.all(inRange.map(day => day.getDayOfMonth()));\n }\n\n /**\n * The day number holding the roving tab stop, or `null` when the grid has none.\n *\n * `null` is a real answer, not a failure: paging with {@link next} leaves the\n * roving date behind in another month, and the grid then has no `tabindex=\"0\"`\n * at all until a key or a click puts one back.\n */\n async getActiveDayNumber(): Promise<number | null> {\n for (const day of await this.getDays()) {\n if (await day.isActive()) return day.getDayOfMonth();\n }\n return null;\n }\n\n /** The month chips, with their state. Throws off the month view. */\n async getMonths(): Promise<WrCalendarChip[]> {\n await this.requireView('month', 'getMonths');\n return this.readChips();\n }\n\n /** The year chips, with their state. Throws off the year view. */\n async getYears(): Promise<WrCalendarChip[]> {\n await this.requireView('year', 'getYears');\n return this.readChips();\n }\n\n /**\n * Click a month or year chip by its printed label — which drops the calendar back\n * one view, the way clicking the header climbed up.\n *\n * Throws on the day view, where there are no chips, and on a label the view does\n * not offer, naming what it does.\n */\n async selectChip(label: string): Promise<void> {\n const view = await this.getView();\n if (view === 'day') {\n throw new Error(\n 'WrCalendarHarness.selectChip(): the calendar is on the day view, which has no chips. Click the ' +\n 'header first — it walks day → month → year.'\n );\n }\n\n for (const chip of await this.locatorForAll('.wr-calendar__chip')()) {\n if ((await chip.text()) === label) {\n await chip.click();\n return;\n }\n }\n\n const offered = (await this.readChips()).map(chip => chip.label);\n throw new Error(`WrCalendarHarness.selectChip(\"${label}\"): the ${view} view offers: ${offered.join(', ')}.`);\n }\n\n /**\n * Press an arrow key — one day left or right, one WEEK up or down.\n *\n * Sent to the host, where the component listens, so this does not depend on jsdom\n * having managed to focus a cell. Under `dir=\"rtl\"` the horizontal pair mirrors:\n * ArrowRight goes back a day, because the grid itself is mirrored.\n */\n async pressArrow(arrow: WrCalendarArrowKey): Promise<void> {\n await (await this.host()).sendKeys(ARROWS[arrow]);\n }\n\n /** Press Home — the first day of the roving cell's week, not of the month. */\n async pressHome(): Promise<void> {\n await (await this.host()).sendKeys(TestKey.HOME);\n }\n\n /** Press End — the last day of the roving cell's week. */\n async pressEnd(): Promise<void> {\n await (await this.host()).sendKeys(TestKey.END);\n }\n\n /** Press PageUp — a month back, or a YEAR back with `shift`. */\n async pressPageUp(options: { shift?: boolean } = {}): Promise<void> {\n const host = await this.host();\n await (options.shift ? host.sendKeys({ shift: true }, TestKey.PAGE_UP) : host.sendKeys(TestKey.PAGE_UP));\n }\n\n /** Press PageDown — a month on, or a YEAR on with `shift`. */\n async pressPageDown(options: { shift?: boolean } = {}): Promise<void> {\n const host = await this.host();\n await (options.shift ? host.sendKeys({ shift: true }, TestKey.PAGE_DOWN) : host.sendKeys(TestKey.PAGE_DOWN));\n }\n\n /** Press Enter — picking the roving day, exactly as clicking it would. */\n async pressEnter(): Promise<void> {\n await (await this.host()).sendKeys(TestKey.ENTER);\n }\n\n /**\n * The role of the element that owns the day rows.\n *\n * Worth asserting rather than assuming: the grid is NOT the host. The host also\n * holds the nav header, and a `role=\"grid\"` may only own rows — so the role sits\n * on the body, and the weekday strip is a row inside it rather than a sibling.\n */\n async getGridRole(): Promise<string | null> {\n const body = await this.locatorForOptional('.wr-calendar__body')();\n return body ? body.getAttribute('role') : null;\n }\n\n /** How many week rows the grid renders — always six, which is what keeps it from reflowing. */\n async getWeekCount(): Promise<number> {\n await this.requireView('day', 'getWeekCount');\n return (await this.locatorForAll('.wr-calendar__week')()).length;\n }\n\n private async readChips(): Promise<WrCalendarChip[]> {\n const chips = await this.locatorForAll('.wr-calendar__chip')();\n\n return Promise.all(\n chips.map(async (chip: TestElement) => ({\n label: await chip.text(),\n selected: (await chip.getAttribute('aria-selected')) === 'true',\n current: await chip.hasClass('wr-calendar__chip--current'),\n disabled: (await chip.getAttribute('aria-disabled')) === 'true',\n }))\n );\n }\n\n private async requireView(view: WrCalendarView, method: string): Promise<void> {\n const current = await this.getView();\n if (current === view) return;\n\n throw new Error(\n `WrCalendarHarness.${method}(): the calendar is showing the ${current} view, not the ${view} one — those ` +\n 'elements are not rendered at all. The header walks day → month → year; clicking a chip walks back down.'\n );\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -775,10 +775,10 @@ class WrCalendar {
775
775
  return 'ArrowRight';
776
776
  return key;
777
777
  }
778
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrCalendar, deps: [], target: i0.ɵɵFactoryTarget.Component });
779
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: WrCalendar, isStandalone: true, selector: "wr-calendar", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, date: { classPropertyName: "date", publicName: "date", isSignal: true, isRequired: false, transformFunction: null }, range: { classPropertyName: "range", publicName: "range", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, dateFilter: { classPropertyName: "dateFilter", publicName: "dateFilter", isSignal: true, isRequired: false, transformFunction: null }, autoFocus: { classPropertyName: "autoFocus", publicName: "autoFocus", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { date: "dateChange", range: "rangeChange" }, host: { listeners: { "keydown": "onKeyDown($event)" }, properties: { "class": "classes()" } }, ngImport: i0, template: "<div class=\"wr-calendar__header\">\n <button\n type=\"button\"\n class=\"wr-calendar__nav wr-calendar__nav--prev\"\n [attr.aria-label]=\"prevLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"prev()\"\n >\n <svg\n width=\"18\"\n height=\"18\"\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=\"m15 18-6-6 6-6\" />\n </svg>\n </button>\n <button\n type=\"button\"\n class=\"wr-calendar__label\"\n [disabled]=\"disabled() || viewMode() === 'year'\"\n (click)=\"onLabelClick()\"\n >\n {{ headerLabel() }}\n </button>\n <button\n type=\"button\"\n class=\"wr-calendar__nav wr-calendar__nav--next\"\n [attr.aria-label]=\"nextLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"next()\"\n >\n <svg\n width=\"18\"\n height=\"18\"\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=\"m9 18 6-6-6-6\" />\n </svg>\n </button>\n</div>\n\n@switch (viewMode()) {\n @case ('day') {\n <!--\n The weekday strip and the week rows are one grid, so they share a wrapper:\n `role=\"grid\"` may only own rows, and as siblings the header row had no grid\n parent at all. `.wr-calendar__body` repeats the host's column gap, so the\n rendered spacing is unchanged.\n -->\n <div class=\"wr-calendar__body\" role=\"grid\">\n <div class=\"wr-calendar__weekdays\" role=\"row\">\n @for (name of weekdayNames(); track name) {\n <span class=\"wr-calendar__weekday\" role=\"columnheader\">{{ name }}</span>\n }\n </div>\n\n <div class=\"wr-calendar__grid\" role=\"rowgroup\" (mouseleave)=\"onCellLeave()\">\n @for (week of weeks(); track $index) {\n <div class=\"wr-calendar__week\" role=\"row\">\n @for (day of week; track trackByTime($index, day)) {\n <button\n type=\"button\"\n class=\"wr-calendar__day\"\n role=\"gridcell\"\n [class.wr-calendar__day--today]=\"isToday(day)\"\n [class.wr-calendar__day--out-of-month]=\"isOutOfMonth(day)\"\n [class.wr-calendar__day--selected]=\"isSelected(day)\"\n [class.wr-calendar__day--in-range]=\"isInRange(day)\"\n [class.wr-calendar__day--range-preview]=\"isInRangePreview(day)\"\n [class.wr-calendar__day--focused]=\"isFocused(day)\"\n [disabled]=\"isDisabled(day)\"\n [attr.tabindex]=\"isFocused(day) ? 0 : -1\"\n [attr.aria-label]=\"dayLabel(day)\"\n [attr.aria-selected]=\"isSelected(day)\"\n [attr.aria-disabled]=\"isDisabled(day)\"\n (click)=\"onCellClick(day)\"\n (mouseenter)=\"onCellEnter(day)\"\n >\n {{ day.getDate() }}\n </button>\n }\n </div>\n }\n </div>\n </div>\n }\n\n @case ('month') {\n <!--\n A listbox owns its arrows, so its options share ONE tab stop: twelve months\n that were each tabbable announced a keyboard model \u2014 arrow to a month, Tab\n out of the list \u2014 that the component did not have. `activeChip()` is where\n the ring is, and it is always an enabled chip.\n -->\n <div class=\"wr-calendar__months\" role=\"listbox\" [attr.aria-label]=\"monthListLabel()\">\n @for (name of monthsView(); track name) {\n <button\n type=\"button\"\n class=\"wr-calendar__chip\"\n role=\"option\"\n [class.wr-calendar__chip--current]=\"isMonthCurrent($index)\"\n [class.wr-calendar__chip--selected]=\"isMonthSelected($index)\"\n [disabled]=\"isMonthDisabled($index)\"\n [attr.tabindex]=\"activeChip() === $index ? 0 : -1\"\n [attr.aria-selected]=\"isMonthSelected($index)\"\n [attr.aria-disabled]=\"isMonthDisabled($index)\"\n (click)=\"onMonthSelect($index)\"\n >\n {{ name }}\n </button>\n }\n </div>\n }\n\n @case ('year') {\n <div class=\"wr-calendar__years\" role=\"listbox\" [attr.aria-label]=\"yearListLabel()\">\n @for (year of yearsView(); track year) {\n <button\n type=\"button\"\n class=\"wr-calendar__chip\"\n role=\"option\"\n [class.wr-calendar__chip--current]=\"isYearCurrent(year)\"\n [class.wr-calendar__chip--selected]=\"isYearSelected(year)\"\n [disabled]=\"isYearDisabled(year)\"\n [attr.tabindex]=\"activeChip() === $index ? 0 : -1\"\n [attr.aria-selected]=\"isYearSelected(year)\"\n [attr.aria-disabled]=\"isYearDisabled(year)\"\n (click)=\"onYearSelect(year)\"\n >\n {{ year }}\n </button>\n }\n </div>\n }\n}\n", encapsulation: i0.ViewEncapsulation.None });
778
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrCalendar, deps: [], target: i0.ɵɵFactoryTarget.Component });
779
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: WrCalendar, isStandalone: true, selector: "wr-calendar", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, date: { classPropertyName: "date", publicName: "date", isSignal: true, isRequired: false, transformFunction: null }, range: { classPropertyName: "range", publicName: "range", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, dateFilter: { classPropertyName: "dateFilter", publicName: "dateFilter", isSignal: true, isRequired: false, transformFunction: null }, autoFocus: { classPropertyName: "autoFocus", publicName: "autoFocus", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { date: "dateChange", range: "rangeChange" }, host: { listeners: { "keydown": "onKeyDown($event)" }, properties: { "class": "classes()" } }, ngImport: i0, template: "<div class=\"wr-calendar__header\">\n <button\n type=\"button\"\n class=\"wr-calendar__nav wr-calendar__nav--prev\"\n [attr.aria-label]=\"prevLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"prev()\"\n >\n <svg\n width=\"18\"\n height=\"18\"\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=\"m15 18-6-6 6-6\" />\n </svg>\n </button>\n <button\n type=\"button\"\n class=\"wr-calendar__label\"\n [disabled]=\"disabled() || viewMode() === 'year'\"\n (click)=\"onLabelClick()\"\n >\n {{ headerLabel() }}\n </button>\n <button\n type=\"button\"\n class=\"wr-calendar__nav wr-calendar__nav--next\"\n [attr.aria-label]=\"nextLabel()\"\n [disabled]=\"disabled()\"\n (click)=\"next()\"\n >\n <svg\n width=\"18\"\n height=\"18\"\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=\"m9 18 6-6-6-6\" />\n </svg>\n </button>\n</div>\n\n@switch (viewMode()) {\n @case ('day') {\n <!--\n The weekday strip and the week rows are one grid, so they share a wrapper:\n `role=\"grid\"` may only own rows, and as siblings the header row had no grid\n parent at all. `.wr-calendar__body` repeats the host's column gap, so the\n rendered spacing is unchanged.\n -->\n <div class=\"wr-calendar__body\" role=\"grid\">\n <div class=\"wr-calendar__weekdays\" role=\"row\">\n @for (name of weekdayNames(); track name) {\n <span class=\"wr-calendar__weekday\" role=\"columnheader\">{{ name }}</span>\n }\n </div>\n\n <div class=\"wr-calendar__grid\" role=\"rowgroup\" (mouseleave)=\"onCellLeave()\">\n @for (week of weeks(); track $index) {\n <div class=\"wr-calendar__week\" role=\"row\">\n @for (day of week; track trackByTime($index, day)) {\n <button\n type=\"button\"\n class=\"wr-calendar__day\"\n role=\"gridcell\"\n [class.wr-calendar__day--today]=\"isToday(day)\"\n [class.wr-calendar__day--out-of-month]=\"isOutOfMonth(day)\"\n [class.wr-calendar__day--selected]=\"isSelected(day)\"\n [class.wr-calendar__day--in-range]=\"isInRange(day)\"\n [class.wr-calendar__day--range-preview]=\"isInRangePreview(day)\"\n [class.wr-calendar__day--focused]=\"isFocused(day)\"\n [disabled]=\"isDisabled(day)\"\n [attr.tabindex]=\"isFocused(day) ? 0 : -1\"\n [attr.aria-label]=\"dayLabel(day)\"\n [attr.aria-selected]=\"isSelected(day)\"\n [attr.aria-disabled]=\"isDisabled(day)\"\n (click)=\"onCellClick(day)\"\n (mouseenter)=\"onCellEnter(day)\"\n >\n {{ day.getDate() }}\n </button>\n }\n </div>\n }\n </div>\n </div>\n }\n\n @case ('month') {\n <!--\n A listbox owns its arrows, so its options share ONE tab stop: twelve months\n that were each tabbable announced a keyboard model \u2014 arrow to a month, Tab\n out of the list \u2014 that the component did not have. `activeChip()` is where\n the ring is, and it is always an enabled chip.\n -->\n <div class=\"wr-calendar__months\" role=\"listbox\" [attr.aria-label]=\"monthListLabel()\">\n @for (name of monthsView(); track name) {\n <button\n type=\"button\"\n class=\"wr-calendar__chip\"\n role=\"option\"\n [class.wr-calendar__chip--current]=\"isMonthCurrent($index)\"\n [class.wr-calendar__chip--selected]=\"isMonthSelected($index)\"\n [disabled]=\"isMonthDisabled($index)\"\n [attr.tabindex]=\"activeChip() === $index ? 0 : -1\"\n [attr.aria-selected]=\"isMonthSelected($index)\"\n [attr.aria-disabled]=\"isMonthDisabled($index)\"\n (click)=\"onMonthSelect($index)\"\n >\n {{ name }}\n </button>\n }\n </div>\n }\n\n @case ('year') {\n <div class=\"wr-calendar__years\" role=\"listbox\" [attr.aria-label]=\"yearListLabel()\">\n @for (year of yearsView(); track year) {\n <button\n type=\"button\"\n class=\"wr-calendar__chip\"\n role=\"option\"\n [class.wr-calendar__chip--current]=\"isYearCurrent(year)\"\n [class.wr-calendar__chip--selected]=\"isYearSelected(year)\"\n [disabled]=\"isYearDisabled(year)\"\n [attr.tabindex]=\"activeChip() === $index ? 0 : -1\"\n [attr.aria-selected]=\"isYearSelected(year)\"\n [attr.aria-disabled]=\"isYearDisabled(year)\"\n (click)=\"onYearSelect(year)\"\n >\n {{ year }}\n </button>\n }\n </div>\n }\n}\n", encapsulation: i0.ViewEncapsulation.None });
780
780
  }
781
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrCalendar, decorators: [{
781
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: WrCalendar, decorators: [{
782
782
  type: Component,
783
783
  args: [{ selector: 'wr-calendar', encapsulation: ViewEncapsulation.None, host: {
784
784
  '[class]': 'classes()',