ngwr 15.0.1 → 15.2.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 (420) hide show
  1. package/anchor/styles/_index.scss +13 -2
  2. package/bits/aurora/styles/_rules.scss +11 -0
  3. package/bits/dot-grid/dot-grid.scss +1 -0
  4. package/bits/dot-grid/styles/_index.scss +8 -0
  5. package/bits/dot-grid/styles/_rules.scss +54 -0
  6. package/bits/iridescence/iridescence.scss +1 -0
  7. package/bits/iridescence/styles/_index.scss +8 -0
  8. package/bits/iridescence/styles/_rules.scss +72 -0
  9. package/bits/marquee/styles/_rules.scss +7 -3
  10. package/bits/ripple-grid/ripple-grid.scss +1 -0
  11. package/bits/ripple-grid/styles/_index.scss +8 -0
  12. package/bits/ripple-grid/styles/_rules.scss +63 -0
  13. package/bits/spotlight-card/styles/_rules.scss +7 -4
  14. package/bits/star-border/styles/_rules.scss +5 -2
  15. package/bits/threads/styles/_index.scss +8 -0
  16. package/bits/threads/styles/_rules.scss +76 -0
  17. package/bits/threads/threads.scss +1 -0
  18. package/bits/waves/styles/_rules.scss +8 -1
  19. package/charts/bar-chart/styles/_index.scss +607 -7
  20. package/charts/boxplot-chart/styles/_index.scss +297 -0
  21. package/charts/bullet-chart/styles/_index.scss +268 -0
  22. package/charts/calendar-heatmap/styles/_index.scss +25 -3
  23. package/charts/candlestick-chart/styles/_index.scss +307 -0
  24. package/charts/chart-legend/styles/_index.scss +143 -0
  25. package/charts/core/styles/_index.scss +30 -0
  26. package/charts/donut-chart/styles/_index.scss +39 -3
  27. package/charts/funnel-chart/styles/_index.scss +237 -0
  28. package/charts/gauge/styles/_index.scss +4 -2
  29. package/charts/heatmap-chart/styles/_index.scss +329 -0
  30. package/charts/line-chart/styles/_index.scss +141 -8
  31. package/charts/meter-group/styles/_index.scss +44 -13
  32. package/charts/radar-chart/styles/_index.scss +206 -0
  33. package/charts/scatter-chart/styles/_index.scss +245 -0
  34. package/charts/sparkline/styles/_index.scss +10 -1
  35. package/charts/treemap-chart/styles/_index.scss +215 -0
  36. package/charts/waterfall-chart/styles/_index.scss +321 -0
  37. package/collapse/styles/_index.scss +6 -1
  38. package/fesm2022/ngwr-affix.mjs +3 -3
  39. package/fesm2022/ngwr-alert.mjs +3 -3
  40. package/fesm2022/ngwr-anchor.mjs +3 -3
  41. package/fesm2022/ngwr-avatar.mjs +3 -3
  42. package/fesm2022/ngwr-back-top.mjs +3 -3
  43. package/fesm2022/ngwr-badge.mjs +6 -6
  44. package/fesm2022/ngwr-bits-aurora.mjs +30 -38
  45. package/fesm2022/ngwr-bits-aurora.mjs.map +1 -1
  46. package/fesm2022/ngwr-bits-blur-text.mjs +3 -3
  47. package/fesm2022/ngwr-bits-border-glow-testing.mjs.map +1 -1
  48. package/fesm2022/ngwr-bits-border-glow.mjs +11 -5
  49. package/fesm2022/ngwr-bits-border-glow.mjs.map +1 -1
  50. package/fesm2022/ngwr-bits-circular-text.mjs +3 -3
  51. package/fesm2022/ngwr-bits-click-spark.mjs +3 -3
  52. package/fesm2022/ngwr-bits-confetti.mjs +3 -3
  53. package/fesm2022/ngwr-bits-decrypt-text.mjs +3 -3
  54. package/fesm2022/ngwr-bits-dot-grid-testing.mjs +40 -0
  55. package/fesm2022/ngwr-bits-dot-grid-testing.mjs.map +1 -0
  56. package/fesm2022/ngwr-bits-dot-grid.mjs +482 -0
  57. package/fesm2022/ngwr-bits-dot-grid.mjs.map +1 -0
  58. package/fesm2022/ngwr-bits-falling-text.mjs +3 -3
  59. package/fesm2022/ngwr-bits-fuzzy-text.mjs +3 -3
  60. package/fesm2022/ngwr-bits-glitch-text.mjs +3 -3
  61. package/fesm2022/ngwr-bits-gradient-text.mjs +3 -3
  62. package/fesm2022/ngwr-bits-iridescence-testing.mjs +31 -0
  63. package/fesm2022/ngwr-bits-iridescence-testing.mjs.map +1 -0
  64. package/fesm2022/ngwr-bits-iridescence.mjs +591 -0
  65. package/fesm2022/ngwr-bits-iridescence.mjs.map +1 -0
  66. package/fesm2022/ngwr-bits-marquee-testing.mjs +1 -1
  67. package/fesm2022/ngwr-bits-marquee-testing.mjs.map +1 -1
  68. package/fesm2022/ngwr-bits-marquee.mjs +7 -7
  69. package/fesm2022/ngwr-bits-marquee.mjs.map +1 -1
  70. package/fesm2022/ngwr-bits-ripple-grid-testing.mjs +40 -0
  71. package/fesm2022/ngwr-bits-ripple-grid-testing.mjs.map +1 -0
  72. package/fesm2022/ngwr-bits-ripple-grid.mjs +805 -0
  73. package/fesm2022/ngwr-bits-ripple-grid.mjs.map +1 -0
  74. package/fesm2022/ngwr-bits-rotating-text.mjs +3 -3
  75. package/fesm2022/ngwr-bits-shiny-text.mjs +6 -6
  76. package/fesm2022/ngwr-bits-splash-cursor.mjs +3 -3
  77. package/fesm2022/ngwr-bits-split-text.mjs +3 -3
  78. package/fesm2022/ngwr-bits-spotlight-card-testing.mjs +1 -1
  79. package/fesm2022/ngwr-bits-spotlight-card-testing.mjs.map +1 -1
  80. package/fesm2022/ngwr-bits-spotlight-card.mjs +10 -10
  81. package/fesm2022/ngwr-bits-spotlight-card.mjs.map +1 -1
  82. package/fesm2022/ngwr-bits-star-border-testing.mjs +1 -1
  83. package/fesm2022/ngwr-bits-star-border-testing.mjs.map +1 -1
  84. package/fesm2022/ngwr-bits-star-border.mjs +7 -7
  85. package/fesm2022/ngwr-bits-star-border.mjs.map +1 -1
  86. package/fesm2022/ngwr-bits-threads-testing.mjs +41 -0
  87. package/fesm2022/ngwr-bits-threads-testing.mjs.map +1 -0
  88. package/fesm2022/ngwr-bits-threads.mjs +482 -0
  89. package/fesm2022/ngwr-bits-threads.mjs.map +1 -0
  90. package/fesm2022/ngwr-bits-tilt-card.mjs +6 -6
  91. package/fesm2022/ngwr-bits-typewriter.mjs +3 -3
  92. package/fesm2022/ngwr-bits-waves-testing.mjs.map +1 -1
  93. package/fesm2022/ngwr-bits-waves.mjs +60 -41
  94. package/fesm2022/ngwr-bits-waves.mjs.map +1 -1
  95. package/fesm2022/ngwr-breadcrumbs.mjs +8 -8
  96. package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
  97. package/fesm2022/ngwr-burger.mjs +3 -3
  98. package/fesm2022/ngwr-button.mjs +6 -6
  99. package/fesm2022/ngwr-calendar.mjs +3 -3
  100. package/fesm2022/ngwr-card.mjs +9 -9
  101. package/fesm2022/ngwr-carousel.mjs +6 -6
  102. package/fesm2022/ngwr-cascader.mjs +5 -5
  103. package/fesm2022/ngwr-cascader.mjs.map +1 -1
  104. package/fesm2022/ngwr-charts-bar-chart-testing.mjs +127 -3
  105. package/fesm2022/ngwr-charts-bar-chart-testing.mjs.map +1 -1
  106. package/fesm2022/ngwr-charts-bar-chart.mjs +683 -49
  107. package/fesm2022/ngwr-charts-bar-chart.mjs.map +1 -1
  108. package/fesm2022/ngwr-charts-boxplot-chart-testing.mjs +161 -0
  109. package/fesm2022/ngwr-charts-boxplot-chart-testing.mjs.map +1 -0
  110. package/fesm2022/ngwr-charts-boxplot-chart.mjs +517 -0
  111. package/fesm2022/ngwr-charts-boxplot-chart.mjs.map +1 -0
  112. package/fesm2022/ngwr-charts-bullet-chart-testing.mjs +68 -0
  113. package/fesm2022/ngwr-charts-bullet-chart-testing.mjs.map +1 -0
  114. package/fesm2022/ngwr-charts-bullet-chart.mjs +459 -0
  115. package/fesm2022/ngwr-charts-bullet-chart.mjs.map +1 -0
  116. package/fesm2022/ngwr-charts-calendar-heatmap-testing.mjs +27 -0
  117. package/fesm2022/ngwr-charts-calendar-heatmap-testing.mjs.map +1 -1
  118. package/fesm2022/ngwr-charts-calendar-heatmap.mjs +96 -17
  119. package/fesm2022/ngwr-charts-calendar-heatmap.mjs.map +1 -1
  120. package/fesm2022/ngwr-charts-candlestick-chart-testing.mjs +107 -0
  121. package/fesm2022/ngwr-charts-candlestick-chart-testing.mjs.map +1 -0
  122. package/fesm2022/ngwr-charts-candlestick-chart.mjs +508 -0
  123. package/fesm2022/ngwr-charts-candlestick-chart.mjs.map +1 -0
  124. package/fesm2022/ngwr-charts-chart-legend-testing.mjs +126 -0
  125. package/fesm2022/ngwr-charts-chart-legend-testing.mjs.map +1 -0
  126. package/fesm2022/ngwr-charts-chart-legend.mjs +251 -0
  127. package/fesm2022/ngwr-charts-chart-legend.mjs.map +1 -0
  128. package/fesm2022/ngwr-charts-core.mjs +383 -0
  129. package/fesm2022/ngwr-charts-core.mjs.map +1 -0
  130. package/fesm2022/ngwr-charts-donut-chart-testing.mjs +10 -1
  131. package/fesm2022/ngwr-charts-donut-chart-testing.mjs.map +1 -1
  132. package/fesm2022/ngwr-charts-donut-chart.mjs +187 -31
  133. package/fesm2022/ngwr-charts-donut-chart.mjs.map +1 -1
  134. package/fesm2022/ngwr-charts-funnel-chart-testing.mjs +100 -0
  135. package/fesm2022/ngwr-charts-funnel-chart-testing.mjs.map +1 -0
  136. package/fesm2022/ngwr-charts-funnel-chart.mjs +415 -0
  137. package/fesm2022/ngwr-charts-funnel-chart.mjs.map +1 -0
  138. package/fesm2022/ngwr-charts-gauge-testing.mjs +9 -3
  139. package/fesm2022/ngwr-charts-gauge-testing.mjs.map +1 -1
  140. package/fesm2022/ngwr-charts-gauge.mjs +9 -15
  141. package/fesm2022/ngwr-charts-gauge.mjs.map +1 -1
  142. package/fesm2022/ngwr-charts-heatmap-chart-testing.mjs +120 -0
  143. package/fesm2022/ngwr-charts-heatmap-chart-testing.mjs.map +1 -0
  144. package/fesm2022/ngwr-charts-heatmap-chart.mjs +519 -0
  145. package/fesm2022/ngwr-charts-heatmap-chart.mjs.map +1 -0
  146. package/fesm2022/ngwr-charts-line-chart-testing.mjs +43 -1
  147. package/fesm2022/ngwr-charts-line-chart-testing.mjs.map +1 -1
  148. package/fesm2022/ngwr-charts-line-chart.mjs +436 -122
  149. package/fesm2022/ngwr-charts-line-chart.mjs.map +1 -1
  150. package/fesm2022/ngwr-charts-meter-group-testing.mjs +14 -2
  151. package/fesm2022/ngwr-charts-meter-group-testing.mjs.map +1 -1
  152. package/fesm2022/ngwr-charts-meter-group.mjs +101 -32
  153. package/fesm2022/ngwr-charts-meter-group.mjs.map +1 -1
  154. package/fesm2022/ngwr-charts-radar-chart-testing.mjs +98 -0
  155. package/fesm2022/ngwr-charts-radar-chart-testing.mjs.map +1 -0
  156. package/fesm2022/ngwr-charts-radar-chart.mjs +720 -0
  157. package/fesm2022/ngwr-charts-radar-chart.mjs.map +1 -0
  158. package/fesm2022/ngwr-charts-scatter-chart-testing.mjs +132 -0
  159. package/fesm2022/ngwr-charts-scatter-chart-testing.mjs.map +1 -0
  160. package/fesm2022/ngwr-charts-scatter-chart.mjs +545 -0
  161. package/fesm2022/ngwr-charts-scatter-chart.mjs.map +1 -0
  162. package/fesm2022/ngwr-charts-sparkline-testing.mjs.map +1 -1
  163. package/fesm2022/ngwr-charts-sparkline.mjs +14 -16
  164. package/fesm2022/ngwr-charts-sparkline.mjs.map +1 -1
  165. package/fesm2022/ngwr-charts-treemap-chart-testing.mjs +103 -0
  166. package/fesm2022/ngwr-charts-treemap-chart-testing.mjs.map +1 -0
  167. package/fesm2022/ngwr-charts-treemap-chart.mjs +535 -0
  168. package/fesm2022/ngwr-charts-treemap-chart.mjs.map +1 -0
  169. package/fesm2022/ngwr-charts-waterfall-chart-testing.mjs +131 -0
  170. package/fesm2022/ngwr-charts-waterfall-chart-testing.mjs.map +1 -0
  171. package/fesm2022/ngwr-charts-waterfall-chart.mjs +462 -0
  172. package/fesm2022/ngwr-charts-waterfall-chart.mjs.map +1 -0
  173. package/fesm2022/ngwr-checkbox.mjs +6 -6
  174. package/fesm2022/ngwr-clipboard.mjs +3 -3
  175. package/fesm2022/ngwr-collapse.mjs +9 -9
  176. package/fesm2022/ngwr-color-picker.mjs +6 -6
  177. package/fesm2022/ngwr-command-palette.mjs +3 -3
  178. package/fesm2022/ngwr-compare.mjs +3 -3
  179. package/fesm2022/ngwr-context-menu.mjs +12 -12
  180. package/fesm2022/ngwr-cookie.mjs +3 -3
  181. package/fesm2022/ngwr-counter.mjs +6 -6
  182. package/fesm2022/ngwr-date-picker.mjs +21 -21
  183. package/fesm2022/ngwr-date.mjs +6 -6
  184. package/fesm2022/ngwr-density.mjs +6 -6
  185. package/fesm2022/ngwr-descriptions.mjs +6 -6
  186. package/fesm2022/ngwr-dialog.mjs +15 -15
  187. package/fesm2022/ngwr-directives.mjs +12 -12
  188. package/fesm2022/ngwr-divider.mjs +3 -3
  189. package/fesm2022/ngwr-drawer.mjs +18 -18
  190. package/fesm2022/ngwr-dropdown.mjs +9 -9
  191. package/fesm2022/ngwr-editor.mjs +3 -3
  192. package/fesm2022/ngwr-empty.mjs +3 -3
  193. package/fesm2022/ngwr-event-calendar.mjs +6 -6
  194. package/fesm2022/ngwr-file-upload.mjs +3 -3
  195. package/fesm2022/ngwr-form.mjs +9 -9
  196. package/fesm2022/ngwr-graph.mjs +6 -6
  197. package/fesm2022/ngwr-hotkey.mjs +6 -6
  198. package/fesm2022/ngwr-i18n-ar.mjs +90 -4
  199. package/fesm2022/ngwr-i18n-ar.mjs.map +1 -1
  200. package/fesm2022/ngwr-i18n-cs.mjs +90 -4
  201. package/fesm2022/ngwr-i18n-cs.mjs.map +1 -1
  202. package/fesm2022/ngwr-i18n-de.mjs +90 -4
  203. package/fesm2022/ngwr-i18n-de.mjs.map +1 -1
  204. package/fesm2022/ngwr-i18n-en.mjs +90 -4
  205. package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
  206. package/fesm2022/ngwr-i18n-es.mjs +90 -4
  207. package/fesm2022/ngwr-i18n-es.mjs.map +1 -1
  208. package/fesm2022/ngwr-i18n-fr.mjs +90 -4
  209. package/fesm2022/ngwr-i18n-fr.mjs.map +1 -1
  210. package/fesm2022/ngwr-i18n-he.mjs +90 -4
  211. package/fesm2022/ngwr-i18n-he.mjs.map +1 -1
  212. package/fesm2022/ngwr-i18n-hi.mjs +90 -4
  213. package/fesm2022/ngwr-i18n-hi.mjs.map +1 -1
  214. package/fesm2022/ngwr-i18n-id.mjs +90 -4
  215. package/fesm2022/ngwr-i18n-id.mjs.map +1 -1
  216. package/fesm2022/ngwr-i18n-it.mjs +90 -4
  217. package/fesm2022/ngwr-i18n-it.mjs.map +1 -1
  218. package/fesm2022/ngwr-i18n-ja.mjs +90 -4
  219. package/fesm2022/ngwr-i18n-ja.mjs.map +1 -1
  220. package/fesm2022/ngwr-i18n-ko.mjs +90 -4
  221. package/fesm2022/ngwr-i18n-ko.mjs.map +1 -1
  222. package/fesm2022/ngwr-i18n-nl.mjs +90 -4
  223. package/fesm2022/ngwr-i18n-nl.mjs.map +1 -1
  224. package/fesm2022/ngwr-i18n-pl.mjs +90 -4
  225. package/fesm2022/ngwr-i18n-pl.mjs.map +1 -1
  226. package/fesm2022/ngwr-i18n-pt.mjs +90 -4
  227. package/fesm2022/ngwr-i18n-pt.mjs.map +1 -1
  228. package/fesm2022/ngwr-i18n-ru.mjs +90 -4
  229. package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
  230. package/fesm2022/ngwr-i18n-sv.mjs +90 -4
  231. package/fesm2022/ngwr-i18n-sv.mjs.map +1 -1
  232. package/fesm2022/ngwr-i18n-tr.mjs +90 -4
  233. package/fesm2022/ngwr-i18n-tr.mjs.map +1 -1
  234. package/fesm2022/ngwr-i18n-uk.mjs +90 -4
  235. package/fesm2022/ngwr-i18n-uk.mjs.map +1 -1
  236. package/fesm2022/ngwr-i18n-vi.mjs +90 -4
  237. package/fesm2022/ngwr-i18n-vi.mjs.map +1 -1
  238. package/fesm2022/ngwr-i18n-zh-tw.mjs +90 -4
  239. package/fesm2022/ngwr-i18n-zh-tw.mjs.map +1 -1
  240. package/fesm2022/ngwr-i18n-zh.mjs +90 -4
  241. package/fesm2022/ngwr-i18n-zh.mjs.map +1 -1
  242. package/fesm2022/ngwr-i18n.mjs +9 -9
  243. package/fesm2022/ngwr-icon.mjs +6 -6
  244. package/fesm2022/ngwr-image-cropper.mjs +3 -3
  245. package/fesm2022/ngwr-input-number.mjs +3 -3
  246. package/fesm2022/ngwr-input-otp.mjs +3 -3
  247. package/fesm2022/ngwr-input.mjs +15 -15
  248. package/fesm2022/ngwr-keyboard.mjs +3 -3
  249. package/fesm2022/ngwr-knob.mjs +3 -3
  250. package/fesm2022/ngwr-layout.mjs +15 -15
  251. package/fesm2022/ngwr-lightbox.mjs +5 -5
  252. package/fesm2022/ngwr-lightbox.mjs.map +1 -1
  253. package/fesm2022/ngwr-list.mjs +8 -8
  254. package/fesm2022/ngwr-list.mjs.map +1 -1
  255. package/fesm2022/ngwr-loading-bar.mjs +6 -6
  256. package/fesm2022/ngwr-mention.mjs +6 -6
  257. package/fesm2022/ngwr-meta.mjs +6 -6
  258. package/fesm2022/ngwr-overlay.mjs +6 -6
  259. package/fesm2022/ngwr-page-header.mjs +3 -3
  260. package/fesm2022/ngwr-pagination.mjs +3 -3
  261. package/fesm2022/ngwr-pipes.mjs +21 -21
  262. package/fesm2022/ngwr-platform.mjs +6 -6
  263. package/fesm2022/ngwr-popconfirm.mjs +6 -6
  264. package/fesm2022/ngwr-popover.mjs +43 -20
  265. package/fesm2022/ngwr-popover.mjs.map +1 -1
  266. package/fesm2022/ngwr-progress.mjs +3 -3
  267. package/fesm2022/ngwr-pull-to-refresh.mjs +3 -3
  268. package/fesm2022/ngwr-qr.mjs +4 -3
  269. package/fesm2022/ngwr-qr.mjs.map +1 -1
  270. package/fesm2022/ngwr-radio.mjs +6 -6
  271. package/fesm2022/ngwr-rating.mjs +3 -3
  272. package/fesm2022/ngwr-result.mjs +12 -12
  273. package/fesm2022/ngwr-schema-form.mjs +3 -3
  274. package/fesm2022/ngwr-scroll.mjs +3 -3
  275. package/fesm2022/ngwr-segmented.mjs +3 -3
  276. package/fesm2022/ngwr-select.mjs +12 -12
  277. package/fesm2022/ngwr-sidebar.mjs +3 -3
  278. package/fesm2022/ngwr-skeleton.mjs +3 -3
  279. package/fesm2022/ngwr-slider.mjs +3 -3
  280. package/fesm2022/ngwr-sortable-list.mjs +11 -11
  281. package/fesm2022/ngwr-sortable-list.mjs.map +1 -1
  282. package/fesm2022/ngwr-speed-dial.mjs +3 -3
  283. package/fesm2022/ngwr-spinner.mjs +3 -3
  284. package/fesm2022/ngwr-splitter.mjs +3 -3
  285. package/fesm2022/ngwr-statistic.mjs +9 -9
  286. package/fesm2022/ngwr-stepper.mjs +6 -6
  287. package/fesm2022/ngwr-storage.mjs +3 -3
  288. package/fesm2022/ngwr-switch.mjs +3 -3
  289. package/fesm2022/ngwr-table.mjs +18 -18
  290. package/fesm2022/ngwr-tabs-router.mjs +3 -3
  291. package/fesm2022/ngwr-tabs.mjs +6 -6
  292. package/fesm2022/ngwr-textarea.mjs +3 -3
  293. package/fesm2022/ngwr-theme.mjs +3 -3
  294. package/fesm2022/ngwr-timeline.mjs +6 -6
  295. package/fesm2022/ngwr-toast-testing.mjs +2 -1
  296. package/fesm2022/ngwr-toast-testing.mjs.map +1 -1
  297. package/fesm2022/ngwr-toast.mjs +34 -15
  298. package/fesm2022/ngwr-toast.mjs.map +1 -1
  299. package/fesm2022/ngwr-toolbar.mjs +3 -3
  300. package/fesm2022/ngwr-tour.mjs +6 -6
  301. package/fesm2022/ngwr-transfer.mjs +3 -3
  302. package/fesm2022/ngwr-tree.mjs +3 -3
  303. package/fesm2022/ngwr-typography.mjs +3 -3
  304. package/fesm2022/ngwr-utils.mjs +31 -1
  305. package/fesm2022/ngwr-utils.mjs.map +1 -1
  306. package/fesm2022/ngwr-version.mjs +1 -1
  307. package/fesm2022/ngwr-version.mjs.map +1 -1
  308. package/fesm2022/ngwr-virtual-scroll.mjs +3 -3
  309. package/fesm2022/ngwr-window-testing.mjs +61 -5
  310. package/fesm2022/ngwr-window-testing.mjs.map +1 -1
  311. package/fesm2022/ngwr-window.mjs +1538 -895
  312. package/fesm2022/ngwr-window.mjs.map +1 -1
  313. package/fesm2022/ngwr.mjs.map +1 -1
  314. package/i18n/ar.json +84 -4
  315. package/i18n/cs.json +84 -4
  316. package/i18n/de.json +84 -4
  317. package/i18n/en.json +84 -4
  318. package/i18n/es.json +84 -4
  319. package/i18n/fr.json +84 -4
  320. package/i18n/he.json +84 -4
  321. package/i18n/hi.json +84 -4
  322. package/i18n/id.json +84 -4
  323. package/i18n/it.json +84 -4
  324. package/i18n/ja.json +84 -4
  325. package/i18n/ko.json +84 -4
  326. package/i18n/nl.json +84 -4
  327. package/i18n/pl.json +84 -4
  328. package/i18n/pt.json +84 -4
  329. package/i18n/ru.json +84 -4
  330. package/i18n/sv.json +84 -4
  331. package/i18n/tr.json +84 -4
  332. package/i18n/uk.json +84 -4
  333. package/i18n/vi.json +84 -4
  334. package/i18n/zh-TW.json +84 -4
  335. package/i18n/zh.json +84 -4
  336. package/llms-full.txt +266 -9
  337. package/llms.txt +30 -7
  338. package/mcp/api.js +69 -1
  339. package/mcp/catalog.js +10 -1
  340. package/mcp/server.js +15 -1
  341. package/mcp/tools.js +122 -26
  342. package/package.json +132 -1
  343. package/popover/styles/_index.scss +75 -7
  344. package/schematics/component-style/index.js +3 -0
  345. package/schematics/migrations/v15/index.js +3 -26
  346. package/schematics/ng-add/index.js +2 -2
  347. package/schematics/use/symbol-map.json +14 -0
  348. package/schematics/utility/global-styles.js +19 -4
  349. package/schematics/utility/v15-moves.js +55 -0
  350. package/skills/ngwr/SKILL.md +8 -2
  351. package/skills/ngwr/references/catalog.md +28 -0
  352. package/skills/ngwr/references/setup.md +5 -4
  353. package/theme/styles/_focus.scss +8 -0
  354. package/toast/styles/_index.scss +103 -12
  355. package/types/ngwr-bits-aurora.d.ts +11 -0
  356. package/types/ngwr-bits-border-glow-testing.d.ts +5 -6
  357. package/types/ngwr-bits-border-glow.d.ts +5 -1
  358. package/types/ngwr-bits-dot-grid-testing.d.ts +92 -0
  359. package/types/ngwr-bits-dot-grid.d.ts +158 -0
  360. package/types/ngwr-bits-iridescence-testing.d.ts +85 -0
  361. package/types/ngwr-bits-iridescence.d.ts +244 -0
  362. package/types/ngwr-bits-ripple-grid-testing.d.ts +96 -0
  363. package/types/ngwr-bits-ripple-grid.d.ts +294 -0
  364. package/types/ngwr-bits-splash-cursor.d.ts +0 -1
  365. package/types/ngwr-bits-spotlight-card-testing.d.ts +3 -1
  366. package/types/ngwr-bits-star-border-testing.d.ts +7 -7
  367. package/types/ngwr-bits-threads-testing.d.ts +97 -0
  368. package/types/ngwr-bits-threads.d.ts +216 -0
  369. package/types/ngwr-bits-waves-testing.d.ts +1 -1
  370. package/types/ngwr-bits-waves.d.ts +20 -3
  371. package/types/ngwr-charts-bar-chart-testing.d.ts +193 -14
  372. package/types/ngwr-charts-bar-chart.d.ts +546 -38
  373. package/types/ngwr-charts-boxplot-chart-testing.d.ts +165 -0
  374. package/types/ngwr-charts-boxplot-chart.d.ts +308 -0
  375. package/types/ngwr-charts-bullet-chart-testing.d.ts +99 -0
  376. package/types/ngwr-charts-bullet-chart.d.ts +262 -0
  377. package/types/ngwr-charts-calendar-heatmap-testing.d.ts +32 -1
  378. package/types/ngwr-charts-calendar-heatmap.d.ts +55 -6
  379. package/types/ngwr-charts-candlestick-chart-testing.d.ts +135 -0
  380. package/types/ngwr-charts-candlestick-chart.d.ts +361 -0
  381. package/types/ngwr-charts-chart-legend-testing.d.ts +84 -0
  382. package/types/ngwr-charts-chart-legend.d.ts +178 -0
  383. package/types/ngwr-charts-core.d.ts +391 -0
  384. package/types/ngwr-charts-donut-chart-testing.d.ts +28 -5
  385. package/types/ngwr-charts-donut-chart.d.ts +124 -12
  386. package/types/ngwr-charts-funnel-chart-testing.d.ts +130 -0
  387. package/types/ngwr-charts-funnel-chart.d.ts +296 -0
  388. package/types/ngwr-charts-gauge-testing.d.ts +5 -0
  389. package/types/ngwr-charts-gauge.d.ts +6 -4
  390. package/types/ngwr-charts-heatmap-chart-testing.d.ts +148 -0
  391. package/types/ngwr-charts-heatmap-chart.d.ts +359 -0
  392. package/types/ngwr-charts-line-chart-testing.d.ts +72 -11
  393. package/types/ngwr-charts-line-chart.d.ts +291 -67
  394. package/types/ngwr-charts-meter-group-testing.d.ts +16 -2
  395. package/types/ngwr-charts-meter-group.d.ts +71 -11
  396. package/types/ngwr-charts-radar-chart-testing.d.ts +162 -0
  397. package/types/ngwr-charts-radar-chart.d.ts +461 -0
  398. package/types/ngwr-charts-scatter-chart-testing.d.ts +147 -0
  399. package/types/ngwr-charts-scatter-chart.d.ts +396 -0
  400. package/types/ngwr-charts-sparkline-testing.d.ts +4 -1
  401. package/types/ngwr-charts-sparkline.d.ts +8 -6
  402. package/types/ngwr-charts-treemap-chart-testing.d.ts +131 -0
  403. package/types/ngwr-charts-treemap-chart.d.ts +295 -0
  404. package/types/ngwr-charts-waterfall-chart-testing.d.ts +149 -0
  405. package/types/ngwr-charts-waterfall-chart.d.ts +338 -0
  406. package/types/ngwr-color-picker.d.ts +0 -21
  407. package/types/ngwr-dropdown.d.ts +0 -52
  408. package/types/ngwr-editor.d.ts +2 -84
  409. package/types/ngwr-i18n.d.ts +0 -15
  410. package/types/ngwr-mention.d.ts +0 -13
  411. package/types/ngwr-popconfirm.d.ts +0 -33
  412. package/types/ngwr-popover.d.ts +29 -53
  413. package/types/ngwr-toast-testing.d.ts +6 -1
  414. package/types/ngwr-tour.d.ts +0 -2
  415. package/types/ngwr-utils.d.ts +49 -7
  416. package/types/ngwr-version.d.ts +1 -1
  417. package/types/ngwr-window-testing.d.ts +65 -7
  418. package/types/ngwr-window.d.ts +831 -207
  419. package/types/ngwr.d.ts +1 -0
  420. package/window/styles/_index.scss +528 -82
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-charts-sparkline-testing.mjs","names":[],"sources":["../../../projects/lib/charts/sparkline/testing/wr-sparkline-harness.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 { WrSparklineHarnessFilters } from './types';\n\n/**\n * Test harness for `<wr-sparkline>`.\n *\n * **The interesting assertion here is the ARIA one.** A sparkline is a trend line\n * with no axes and no labels, so it is either given an `ariaLabel` — in which case it\n * announces itself as an image — or it is decoration, and must be `aria-hidden` so a\n * screen reader does not stop on a nameless graphic. The component switches between\n * those two states on one input, and {@link isDecorative} is how a spec pins which\n * one it is in.\n *\n * The line itself is an SVG path, and a path's `d` is not something a spec should\n * assert: it is a rendering detail that changes with the viewBox, the stroke width\n * and the smoothing. What IS worth asserting is whether the parts are there —\n * {@link hasLine}, {@link hasArea}, {@link hasTip} — since each is an input the\n * consumer set, and an empty dataset draws none of them.\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrSparklineHarness extends ComponentHarness {\n static hostSelector = 'wr-sparkline';\n\n /** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */\n static with(options: WrSparklineHarnessFilters = {}): HarnessPredicate<WrSparklineHarness> {\n return new HarnessPredicate(WrSparklineHarness, options).addOption(\n 'ariaLabel',\n options.ariaLabel,\n (harness, label) => HarnessPredicate.stringMatches(harness.getAccessibleName(), label)\n );\n }\n\n private readonly svg = this.locatorFor('svg');\n\n /** The name the chart announces, or `null` when it is decoration. */\n async getAccessibleName(): Promise<string | null> {\n return (await this.svg()).getAttribute('aria-label');\n }\n\n /** The role the chart claims — `img` when it is named, `null` when it is not. */\n async getRole(): Promise<string | null> {\n return (await this.svg()).getAttribute('role');\n }\n\n /**\n * Whether the chart is hidden from assistive tech.\n *\n * The other half of {@link getAccessibleName}, and the pairing worth asserting\n * together: a named sparkline must NOT be hidden, and an unnamed one must be, or a\n * screen reader announces a graphic with nothing to say about it.\n */\n async isDecorative(): Promise<boolean> {\n return (await (await this.svg()).getAttribute('aria-hidden')) === 'true';\n }\n\n /** Whether a trend line was drawn — `false` for an empty or single-point dataset. */\n async hasLine(): Promise<boolean> {\n return (await this.locatorForOptional('.wr-sparkline__line')()) !== null;\n }\n\n /** Whether the area under the line is filled (`showArea`). */\n async hasArea(): Promise<boolean> {\n return (await this.locatorForOptional('.wr-sparkline__area')()) !== null;\n }\n\n /** Whether the last point is marked with a dot (`showTip`). */\n async hasTip(): Promise<boolean> {\n return (await this.locatorForOptional('.wr-sparkline__tip')()) !== null;\n }\n\n /** The stroke colour as the component passed it through — a CSS value, not a resolved one. */\n async getColor(): Promise<string | null> {\n const line = await this.locatorForOptional('.wr-sparkline__line')();\n return line ? line.getAttribute('stroke') : null;\n }\n}\n"],"mappings":";;;;;;;AA6BA,IAAa,qBAAb,MAAa,2BAA2B,iBAAgB;CACtD,OAAO,eAAe;CAGtB,OAAO,KAAK,UAAqC,CAAA,GAAE;EACjD,OAAO,IAAI,iBAAiB,oBAAoB,OAAO,CAAC,CAAC,UACvD,aACA,QAAQ,YACP,SAAS,UAAU,iBAAiB,cAAc,QAAQ,kBAAiB,GAAI,KAAK,CAAC;CAE1F;CAEiB,MAAM,KAAK,WAAW,KAAK;CAG5C,MAAM,oBAAiB;EACrB,QAAQ,MAAM,KAAK,IAAG,EAAA,CAAI,aAAa,YAAY;CACrD;CAGA,MAAM,UAAO;EACX,QAAQ,MAAM,KAAK,IAAG,EAAA,CAAI,aAAa,MAAM;CAC/C;CASA,MAAM,eAAY;EAChB,OAAQ,OAAO,MAAM,KAAK,IAAG,EAAA,CAAI,aAAa,aAAa,MAAO;CACpE;CAGA,MAAM,UAAO;EACX,OAAQ,MAAM,KAAK,mBAAmB,qBAAqB,CAAC,CAAA,MAAQ;CACtE;CAGA,MAAM,UAAO;EACX,OAAQ,MAAM,KAAK,mBAAmB,qBAAqB,CAAC,CAAA,MAAQ;CACtE;CAGA,MAAM,SAAM;EACV,OAAQ,MAAM,KAAK,mBAAmB,oBAAoB,CAAC,CAAA,MAAQ;CACrE;CAGA,MAAM,WAAQ;EACZ,MAAM,OAAO,MAAM,KAAK,mBAAmB,qBAAqB,CAAC,CAAA;EACjE,OAAO,OAAO,KAAK,aAAa,QAAQ,IAAI;CAC9C"}
1
+ {"version":3,"file":"ngwr-charts-sparkline-testing.mjs","names":[],"sources":["../../../projects/lib/charts/sparkline/testing/wr-sparkline-harness.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 { WrSparklineHarnessFilters } from './types';\n\n/**\n * Test harness for `<wr-sparkline>`.\n *\n * **The interesting assertion here is the ARIA one.** A sparkline is a trend line\n * with no axes and no labels, so it is either given an `ariaLabel` — in which case it\n * announces itself as an image — or it is decoration, and must be `aria-hidden` so a\n * screen reader does not stop on a nameless graphic. The component switches between\n * those two states on one input, and {@link isDecorative} is how a spec pins which\n * one it is in.\n *\n * The line itself is an SVG path, and a path's `d` is not something a spec should\n * assert: it is a rendering detail that changes with the viewBox, the stroke width\n * and the smoothing. What IS worth asserting is whether the parts are there —\n * {@link hasLine}, {@link hasArea}, {@link hasTip} — since each is an input the\n * consumer set, and an empty dataset draws none of them.\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrSparklineHarness extends ComponentHarness {\n static hostSelector = 'wr-sparkline';\n\n /** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */\n static with(options: WrSparklineHarnessFilters = {}): HarnessPredicate<WrSparklineHarness> {\n return new HarnessPredicate(WrSparklineHarness, options).addOption(\n 'ariaLabel',\n options.ariaLabel,\n (harness, label) => HarnessPredicate.stringMatches(harness.getAccessibleName(), label)\n );\n }\n\n private readonly svg = this.locatorFor('svg');\n\n /** The name the chart announces, or `null` when it is decoration. */\n async getAccessibleName(): Promise<string | null> {\n return (await this.svg()).getAttribute('aria-label');\n }\n\n /** The role the chart claims — `img` when it is named, `null` when it is not. */\n async getRole(): Promise<string | null> {\n return (await this.svg()).getAttribute('role');\n }\n\n /**\n * Whether the chart is hidden from assistive tech.\n *\n * The other half of {@link getAccessibleName}, and the pairing worth asserting\n * together: a named sparkline must NOT be hidden, and an unnamed one must be, or a\n * screen reader announces a graphic with nothing to say about it.\n */\n async isDecorative(): Promise<boolean> {\n return (await (await this.svg()).getAttribute('aria-hidden')) === 'true';\n }\n\n /**\n * Whether a trend line was drawn — `false` for an empty dataset. A single point is a\n * line that returns to its start, which the round cap paints as a dot, so it is `true`.\n */\n async hasLine(): Promise<boolean> {\n return (await this.locatorForOptional('.wr-sparkline__line')()) !== null;\n }\n\n /** Whether the area under the line is filled (`showArea`). */\n async hasArea(): Promise<boolean> {\n return (await this.locatorForOptional('.wr-sparkline__area')()) !== null;\n }\n\n /** Whether the last point is marked with a dot (`showTip`). */\n async hasTip(): Promise<boolean> {\n return (await this.locatorForOptional('.wr-sparkline__tip')()) !== null;\n }\n\n /** The stroke colour as the component passed it through — a CSS value, not a resolved one. */\n async getColor(): Promise<string | null> {\n const line = await this.locatorForOptional('.wr-sparkline__line')();\n return line ? line.getAttribute('stroke') : null;\n }\n}\n"],"mappings":";;;;;;;AA6BA,IAAa,qBAAb,MAAa,2BAA2B,iBAAgB;CACtD,OAAO,eAAe;CAGtB,OAAO,KAAK,UAAqC,CAAA,GAAE;EACjD,OAAO,IAAI,iBAAiB,oBAAoB,OAAO,CAAC,CAAC,UACvD,aACA,QAAQ,YACP,SAAS,UAAU,iBAAiB,cAAc,QAAQ,kBAAiB,GAAI,KAAK,CAAC;CAE1F;CAEiB,MAAM,KAAK,WAAW,KAAK;CAG5C,MAAM,oBAAiB;EACrB,QAAQ,MAAM,KAAK,IAAG,EAAA,CAAI,aAAa,YAAY;CACrD;CAGA,MAAM,UAAO;EACX,QAAQ,MAAM,KAAK,IAAG,EAAA,CAAI,aAAa,MAAM;CAC/C;CASA,MAAM,eAAY;EAChB,OAAQ,OAAO,MAAM,KAAK,IAAG,EAAA,CAAI,aAAa,aAAa,MAAO;CACpE;CAMA,MAAM,UAAO;EACX,OAAQ,MAAM,KAAK,mBAAmB,qBAAqB,CAAC,CAAA,MAAQ;CACtE;CAGA,MAAM,UAAO;EACX,OAAQ,MAAM,KAAK,mBAAmB,qBAAqB,CAAC,CAAA,MAAQ;CACtE;CAGA,MAAM,SAAM;EACV,OAAQ,MAAM,KAAK,mBAAmB,oBAAoB,CAAC,CAAA,MAAQ;CACrE;CAGA,MAAM,WAAQ;EACZ,MAAM,OAAO,MAAM,KAAK,mBAAmB,qBAAqB,CAAC,CAAA;EACjE,OAAO,OAAO,KAAK,aAAa,QAAQ,IAAI;CAC9C"}
@@ -1,6 +1,7 @@
1
1
  import * as i0 from "@angular/core";
2
- import { Component, ElementRef, LOCALE_ID, ViewEncapsulation, computed, inject, input, viewChild } from "@angular/core";
2
+ import { Component, ElementRef, ViewEncapsulation, computed, inject, input, viewChild } from "@angular/core";
3
3
  import { coerceBooleanProperty, coerceNumberProperty } from "@angular/cdk/coercion";
4
+ import { useChartNumbers } from "ngwr/charts/core";
4
5
  import { useChartTooltip } from "ngwr/popover";
5
6
  /**
6
7
  * @license
@@ -31,14 +32,7 @@ var WrSparkline = class WrSparkline {
31
32
  transform: coerceBooleanProperty
32
33
  });
33
34
  valueFormat = input(null, ...ngDevMode ? [{ debugName: "valueFormat" }] : /* istanbul ignore next */ []);
34
- locale = inject(LOCALE_ID);
35
- numbers = new Intl.NumberFormat(this.locale);
36
- smallNumbers = new Intl.NumberFormat(this.locale, { maximumSignificantDigits: 3 });
37
- formatValue(value) {
38
- const custom = this.valueFormat();
39
- if (custom) return custom(value);
40
- return (value !== 0 && Math.abs(value) < 1 ? this.smallNumbers : this.numbers).format(value);
41
- }
35
+ numbers = useChartNumbers(this.valueFormat);
42
36
  host = inject(ElementRef);
43
37
  svg = viewChild("svg", ...ngDevMode ? [{ debugName: "svg" }] : /* istanbul ignore next */ []);
44
38
  marker = viewChild("marker", ...ngDevMode ? [{ debugName: "marker" }] : /* istanbul ignore next */ []);
@@ -72,7 +66,11 @@ var WrSparkline = class WrSparkline {
72
66
  y: pad + h - (v - min) / span * h
73
67
  }));
74
68
  }, ...ngDevMode ? [{ debugName: "points" }] : /* istanbul ignore next */ []);
75
- linePath = computed(() => this.points().map((p, i) => `${i === 0 ? "M" : "L"} ${p.x.toFixed(2)} ${p.y.toFixed(2)}`).join(" "), ...ngDevMode ? [{ debugName: "linePath" }] : /* istanbul ignore next */ []);
69
+ linePath = computed(() => {
70
+ const points = this.points();
71
+ const path = points.map((p, i) => `${i === 0 ? "M" : "L"} ${p.x.toFixed(2)} ${p.y.toFixed(2)}`).join(" ");
72
+ return points.length === 1 ? `${path} L ${points[0].x.toFixed(2)} ${points[0].y.toFixed(2)}` : path;
73
+ }, ...ngDevMode ? [{ debugName: "linePath" }] : /* istanbul ignore next */ []);
76
74
  areaPath = computed(() => {
77
75
  const pts = this.points();
78
76
  if (pts.length < 2) return "";
@@ -91,7 +89,7 @@ var WrSparkline = class WrSparkline {
91
89
  return {
92
90
  datum: {
93
91
  label: this.ariaLabel() ?? void 0,
94
- value: this.formatValue(value),
92
+ value: this.numbers.value(value),
95
93
  color: this.color()
96
94
  },
97
95
  anchor: marker
@@ -130,7 +128,7 @@ var WrSparkline = class WrSparkline {
130
128
  }
131
129
  static ɵfac = i0.ɵɵngDeclareFactory({
132
130
  minVersion: "12.0.0",
133
- version: "22.2.3",
131
+ version: "22.2.4",
134
132
  ngImport: i0,
135
133
  type: WrSparkline,
136
134
  deps: [],
@@ -138,7 +136,7 @@ var WrSparkline = class WrSparkline {
138
136
  });
139
137
  static ɵcmp = i0.ɵɵngDeclareComponent({
140
138
  minVersion: "17.0.0",
141
- version: "22.2.3",
139
+ version: "22.2.4",
142
140
  type: WrSparkline,
143
141
  isStandalone: true,
144
142
  selector: "wr-sparkline",
@@ -229,13 +227,13 @@ var WrSparkline = class WrSparkline {
229
227
  isSignal: true
230
228
  }],
231
229
  ngImport: i0,
232
- template: "<svg\n #svg\n [attr.viewBox]=\"viewBox\"\n [style.width]=\"width()\"\n [style.height]=\"height()\"\n [attr.role]=\"ariaLabel() ? 'img' : null\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-hidden]=\"ariaLabel() ? null : 'true'\"\n preserveAspectRatio=\"none\"\n (mousemove)=\"onPointerMove($event)\"\n (mouseleave)=\"tip.leave($event)\"\n>\n @if (showArea() && areaPath()) {\n <path class=\"wr-sparkline__area\" [attr.d]=\"areaPath()\" [attr.fill]=\"color()\" fill-opacity=\"0.15\" stroke=\"none\" />\n }\n @if (linePath()) {\n <path\n class=\"wr-sparkline__line\"\n [attr.d]=\"linePath()\"\n fill=\"none\"\n [attr.stroke]=\"color()\"\n [attr.stroke-width]=\"strokeWidth()\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n }\n <!-- A zero-length line with a round cap and a non-scaling stroke, which stays a\n circle however the drawing stretches; a `<circle>` stretched with it, into a\n 21 × 5px pill on the docs' full-width demo. Three times the line's width. -->\n @if (showTip() && tipPath(); as d) {\n <path\n class=\"wr-sparkline__tip\"\n [attr.d]=\"d\"\n fill=\"none\"\n [attr.stroke]=\"color()\"\n [attr.stroke-width]=\"strokeWidth() * 3\"\n stroke-linecap=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n }\n</svg>\n@if (markerAt(); as at) {\n <span\n #marker\n class=\"wr-sparkline__marker\"\n aria-hidden=\"true\"\n [style.left.px]=\"at.x\"\n [style.top.px]=\"at.y\"\n [style.background]=\"color()\"\n ></span>\n}\n",
230
+ template: "<svg\n #svg\n [attr.viewBox]=\"viewBox\"\n [style.width]=\"width()\"\n [style.height]=\"height()\"\n [attr.role]=\"ariaLabel() ? 'img' : null\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-hidden]=\"ariaLabel() ? null : 'true'\"\n preserveAspectRatio=\"none\"\n (mousemove)=\"onPointerMove($event)\"\n (mouseleave)=\"tip.leave($event)\"\n>\n @if (showArea() && areaPath()) {\n <!-- The fill's share of its colour is the stylesheet's, from `--wr-sparkline-area-opacity`. -->\n <path class=\"wr-sparkline__area\" [attr.d]=\"areaPath()\" [attr.fill]=\"color()\" stroke=\"none\" />\n }\n @if (linePath()) {\n <path\n class=\"wr-sparkline__line\"\n [attr.d]=\"linePath()\"\n fill=\"none\"\n [attr.stroke]=\"color()\"\n [attr.stroke-width]=\"strokeWidth()\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n }\n <!-- A zero-length line with a round cap and a non-scaling stroke, which stays a\n circle however the drawing stretches; a `<circle>` stretched with it, into a\n 21 × 5px pill on the docs' full-width demo. Three times the line's width. -->\n @if (showTip() && tipPath(); as d) {\n <path\n class=\"wr-sparkline__tip\"\n [attr.d]=\"d\"\n fill=\"none\"\n [attr.stroke]=\"color()\"\n [attr.stroke-width]=\"strokeWidth() * 3\"\n stroke-linecap=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n }\n</svg>\n@if (markerAt(); as at) {\n <span\n #marker\n class=\"wr-sparkline__marker\"\n aria-hidden=\"true\"\n [style.left.px]=\"at.x\"\n [style.top.px]=\"at.y\"\n [style.background]=\"color()\"\n ></span>\n}\n",
233
231
  encapsulation: i0.ViewEncapsulation.None
234
232
  });
235
233
  };
236
234
  i0.ɵɵngDeclareClassMetadata({
237
235
  minVersion: "12.0.0",
238
- version: "22.2.3",
236
+ version: "22.2.4",
239
237
  ngImport: i0,
240
238
  type: WrSparkline,
241
239
  decorators: [{
@@ -244,7 +242,7 @@ i0.ɵɵngDeclareClassMetadata({
244
242
  selector: "wr-sparkline",
245
243
  encapsulation: ViewEncapsulation.None,
246
244
  host: { class: "wr-sparkline" },
247
- template: "<svg\n #svg\n [attr.viewBox]=\"viewBox\"\n [style.width]=\"width()\"\n [style.height]=\"height()\"\n [attr.role]=\"ariaLabel() ? 'img' : null\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-hidden]=\"ariaLabel() ? null : 'true'\"\n preserveAspectRatio=\"none\"\n (mousemove)=\"onPointerMove($event)\"\n (mouseleave)=\"tip.leave($event)\"\n>\n @if (showArea() && areaPath()) {\n <path class=\"wr-sparkline__area\" [attr.d]=\"areaPath()\" [attr.fill]=\"color()\" fill-opacity=\"0.15\" stroke=\"none\" />\n }\n @if (linePath()) {\n <path\n class=\"wr-sparkline__line\"\n [attr.d]=\"linePath()\"\n fill=\"none\"\n [attr.stroke]=\"color()\"\n [attr.stroke-width]=\"strokeWidth()\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n }\n <!-- A zero-length line with a round cap and a non-scaling stroke, which stays a\n circle however the drawing stretches; a `<circle>` stretched with it, into a\n 21 × 5px pill on the docs' full-width demo. Three times the line's width. -->\n @if (showTip() && tipPath(); as d) {\n <path\n class=\"wr-sparkline__tip\"\n [attr.d]=\"d\"\n fill=\"none\"\n [attr.stroke]=\"color()\"\n [attr.stroke-width]=\"strokeWidth() * 3\"\n stroke-linecap=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n }\n</svg>\n@if (markerAt(); as at) {\n <span\n #marker\n class=\"wr-sparkline__marker\"\n aria-hidden=\"true\"\n [style.left.px]=\"at.x\"\n [style.top.px]=\"at.y\"\n [style.background]=\"color()\"\n ></span>\n}\n"
245
+ template: "<svg\n #svg\n [attr.viewBox]=\"viewBox\"\n [style.width]=\"width()\"\n [style.height]=\"height()\"\n [attr.role]=\"ariaLabel() ? 'img' : null\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-hidden]=\"ariaLabel() ? null : 'true'\"\n preserveAspectRatio=\"none\"\n (mousemove)=\"onPointerMove($event)\"\n (mouseleave)=\"tip.leave($event)\"\n>\n @if (showArea() && areaPath()) {\n <!-- The fill's share of its colour is the stylesheet's, from `--wr-sparkline-area-opacity`. -->\n <path class=\"wr-sparkline__area\" [attr.d]=\"areaPath()\" [attr.fill]=\"color()\" stroke=\"none\" />\n }\n @if (linePath()) {\n <path\n class=\"wr-sparkline__line\"\n [attr.d]=\"linePath()\"\n fill=\"none\"\n [attr.stroke]=\"color()\"\n [attr.stroke-width]=\"strokeWidth()\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n }\n <!-- A zero-length line with a round cap and a non-scaling stroke, which stays a\n circle however the drawing stretches; a `<circle>` stretched with it, into a\n 21 × 5px pill on the docs' full-width demo. Three times the line's width. -->\n @if (showTip() && tipPath(); as d) {\n <path\n class=\"wr-sparkline__tip\"\n [attr.d]=\"d\"\n fill=\"none\"\n [attr.stroke]=\"color()\"\n [attr.stroke-width]=\"strokeWidth() * 3\"\n stroke-linecap=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n }\n</svg>\n@if (markerAt(); as at) {\n <span\n #marker\n class=\"wr-sparkline__marker\"\n aria-hidden=\"true\"\n [style.left.px]=\"at.x\"\n [style.top.px]=\"at.y\"\n [style.background]=\"color()\"\n ></span>\n}\n"
248
246
  }]
249
247
  }],
250
248
  propDecorators: {
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-charts-sparkline.mjs","names":[],"sources":["../../../projects/lib/charts/sparkline/sparkline.ts","../../../projects/lib/charts/sparkline/sparkline.html"],"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, ElementRef, LOCALE_ID, ViewEncapsulation, computed, inject, input, viewChild } from '@angular/core';\n\nimport { useChartTooltip } from 'ngwr/popover';\n\n/**\n * Tiny inline trend line. SVG path drawn from `[data]: number[]` — no\n * axes, no labels, just the shape. Optional area fill + tip dot.\n *\n * @example\n * ```html\n * <wr-sparkline [data]=\"[12, 14, 9, 17, 21, 18, 23]\" />\n * <wr-sparkline [data]=\"prices\" [showArea]=\"true\" color=\"var(--wr-color-success)\" />\n * ```\n *\n * @see https://ngwr.dev/charts/sparkline\n */\n@Component({\n selector: 'wr-sparkline',\n templateUrl: './sparkline.html',\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-sparkline' },\n})\nexport class WrSparkline {\n /**\n * The values, left to right. Evenly spaced — a sparkline carries no x axis, so\n * pass an already-ordered series rather than points with their own timestamps.\n */\n readonly data = input<readonly number[]>([]);\n\n /**\n * Accessible name. A sparkline usually sits beside the number it summarises, where\n * announcing it again is noise — so it is `aria-hidden` by default and becomes a\n * named `role=\"img\"` only when a consumer says what it shows.\n */\n readonly ariaLabel = input<string | null>(null);\n\n /** Stroke colour. @default `var(--wr-color-primary)` */\n readonly color = input<string>('var(--wr-color-primary)');\n\n /**\n * Line thickness in CSS pixels — `vector-effect=\"non-scaling-stroke\"` keeps it at\n * that width whatever the box is stretched to, so it is NOT in viewBox units.\n * @default 1.5\n */\n readonly strokeWidth = input(1.5, {\n transform: (v: unknown): number => Math.max(0.1, coerceNumberProperty(v, 1.5)),\n });\n\n /** Fill the area below the line. @default false */\n readonly showArea = input(false, { transform: coerceBooleanProperty });\n\n /** Show a dot at the last data point. @default true */\n readonly showTip = input(true, { transform: coerceBooleanProperty });\n\n /** CSS width. @default '8rem' */\n readonly width = input<string>('8rem');\n\n /** CSS height. @default '2rem' */\n readonly height = input<string>('2rem');\n\n /**\n * Show a tooltip with the value of the point nearest the pointer, marking that\n * point, and named by `ariaLabel` when one is given. Pointer only. @default true\n */\n readonly tooltip = input(true, { transform: coerceBooleanProperty });\n\n /**\n * Writes the value in the tooltip. `null` uses `Intl.NumberFormat` in `LOCALE_ID`.\n */\n readonly valueFormat = input<((value: number) => string) | null>(null);\n\n private readonly locale = inject(LOCALE_ID);\n private readonly numbers = new Intl.NumberFormat(this.locale);\n /** Below one, by significant digits, which keep 0.0004 from rounding to `0`. */\n private readonly smallNumbers = new Intl.NumberFormat(this.locale, { maximumSignificantDigits: 3 });\n\n private formatValue(value: number): string {\n const custom = this.valueFormat();\n if (custom) return custom(value);\n return (value !== 0 && Math.abs(value) < 1 ? this.smallNumbers : this.numbers).format(value);\n }\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly svg = viewChild<ElementRef<SVGSVGElement>>('svg');\n private readonly marker = viewChild<ElementRef<HTMLElement>>('marker');\n\n // Drawn in a 100×40 viewBox — scales smoothly to any CSS size.\n private readonly vbW = 100;\n private readonly vbH = 40;\n private readonly padding = 2;\n\n /**\n * The data as drawn. Non-finite values are dropped rather than scaled: every\n * `min`/`max` comparison against a NaN is false, so it survived into the scale and\n * `toFixed(2)` wrote the literal text `NaN` into the path `d` — invalid geometry,\n * and the line vanishes. The tooltip reads this list too, so the value it shows is\n * the one under the point it marks.\n */\n private readonly values = computed(() => this.data().filter(v => Number.isFinite(v)));\n\n /** Mapped `{ x, y }` points for the path. */\n protected readonly points = computed(() => {\n const data = this.values();\n if (data.length === 0) return [] as readonly { x: number; y: number }[];\n if (data.length === 1) return [{ x: this.vbW / 2, y: this.vbH / 2 }];\n\n let min = data[0];\n let max = data[0];\n for (const v of data) {\n if (v < min) min = v;\n if (v > max) max = v;\n }\n const pad = this.padding;\n const w = this.vbW - pad * 2;\n const h = this.vbH - pad * 2;\n // A series with no spread has no shape, and dividing by the old `|| 1` fallback\n // pinned every point to `pad + h` — the bottom edge — so a steady series at 500\n // read as rock bottom. Centred instead, which is what a lone datum already does.\n if (max === min) {\n return data.map((_, i) => ({ x: pad + (i / (data.length - 1)) * w, y: this.vbH / 2 }));\n }\n const span = max - min;\n return data.map((v, i) => ({\n x: pad + (i / (data.length - 1)) * w,\n y: pad + h - ((v - min) / span) * h,\n }));\n });\n\n protected readonly linePath = computed(() =>\n this.points()\n .map((p, i) => `${i === 0 ? 'M' : 'L'} ${p.x.toFixed(2)} ${p.y.toFixed(2)}`)\n .join(' ')\n );\n\n protected readonly areaPath = computed(() => {\n const pts = this.points();\n if (pts.length < 2) return '';\n const baseY = this.vbH - this.padding;\n const start = `M ${pts[0].x.toFixed(2)} ${baseY}`;\n const line = pts.map(p => `L ${p.x.toFixed(2)} ${p.y.toFixed(2)}`).join(' ');\n const close = `L ${pts[pts.length - 1].x.toFixed(2)} ${baseY} Z`;\n return `${start} ${line} ${close}`;\n });\n\n /** A zero-length line at the last point, which a round cap paints as the tip dot. */\n protected readonly tipPath = computed(() => {\n const last = this.points().at(-1);\n return last ? `M ${last.x.toFixed(2)} ${last.y.toFixed(2)} h 0` : null;\n });\n\n protected readonly viewBox = `0 0 ${this.vbW} ${this.vbH}`;\n\n /**\n * One tooltip, pointing at the hovered point: above its marker, below it when there\n * is no room. The marker is the anchor element itself, drawn for the point the\n * tooltip reads — it renders before this runs, since both follow `tip.active()`.\n *\n * The chip sits INSIDE the drawing, over the stretch of line above the marker, so the\n * helper is also told which point any spot over the drawing reads: a pointer scrubbing\n * along the top of a sparkline would otherwise land on the chip and stop there.\n */\n protected readonly tip = useChartTooltip(\n this.tooltip,\n index => {\n const value = this.values()[index];\n const marker = this.marker()?.nativeElement;\n if (value === undefined || !marker) return null;\n return {\n datum: { label: this.ariaLabel() ?? undefined, value: this.formatValue(value), color: this.color() },\n anchor: marker,\n };\n },\n (x, y) => {\n const svg = this.svg()?.nativeElement;\n if (!svg) return null;\n const box = svg.getBoundingClientRect();\n if (x < box.left || x > box.right || y < box.top || y > box.bottom) return null;\n return this.indexAt(x, box);\n }\n );\n\n /**\n * The marker's place in pixels from the host's padding edge, measured off the\n * DRAWING's box. An element rather than a `<circle>`: the drawing stretches to\n * any box with `preserveAspectRatio=\"none\"`, which would squash a circle into an\n * ellipse.\n *\n * Not percentages of the host, which is what it was: the host is only the\n * drawing's size until something stretches it — `width: 100%` on the element,\n * `display: block`, a column flex parent — while the drawing keeps its `width`.\n * Measured in Chromium, WebKit and Firefox on a 327px host round the default\n * 128px drawing, the marker for a point at 115px landed at 292px, out in empty\n * space with the chip above it. Read when a point is hovered, so the boxes are\n * laid out; `tip.active()` is never set on the server.\n */\n protected readonly markerAt = computed(() => {\n const index = this.tip.active();\n const point = index === null ? undefined : this.points()[index];\n const svg = this.svg()?.nativeElement;\n if (!point || !svg) return null;\n const host = this.host.nativeElement;\n const outer = host.getBoundingClientRect();\n const box = svg.getBoundingClientRect();\n return {\n x: box.left - outer.left - host.clientLeft + (point.x / this.vbW) * box.width,\n y: box.top - outer.top - host.clientTop + (point.y / this.vbH) * box.height,\n };\n });\n\n protected onPointerMove(event: MouseEvent): void {\n const index = this.indexAt(event.clientX, (event.currentTarget as Element).getBoundingClientRect());\n if (index !== null) this.tip.enter(index);\n }\n\n /**\n * The point nearest the pointer, along x only — the points are evenly spaced, so\n * that is a rounding rather than a search. A box with no width (nothing laid out\n * yet) answers nothing rather than a NaN index.\n */\n private indexAt(clientX: number, box: DOMRect): number | null {\n const count = this.points().length;\n if (count === 0 || box.width <= 0) return null;\n if (count === 1) return 0;\n const x = ((clientX - box.left) / box.width) * this.vbW;\n const step = (this.vbW - this.padding * 2) / (count - 1);\n return Math.min(count - 1, Math.max(0, Math.round((x - this.padding) / step)));\n }\n}\n","<svg\n #svg\n [attr.viewBox]=\"viewBox\"\n [style.width]=\"width()\"\n [style.height]=\"height()\"\n [attr.role]=\"ariaLabel() ? 'img' : null\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-hidden]=\"ariaLabel() ? null : 'true'\"\n preserveAspectRatio=\"none\"\n (mousemove)=\"onPointerMove($event)\"\n (mouseleave)=\"tip.leave($event)\"\n>\n @if (showArea() && areaPath()) {\n <path class=\"wr-sparkline__area\" [attr.d]=\"areaPath()\" [attr.fill]=\"color()\" fill-opacity=\"0.15\" stroke=\"none\" />\n }\n @if (linePath()) {\n <path\n class=\"wr-sparkline__line\"\n [attr.d]=\"linePath()\"\n fill=\"none\"\n [attr.stroke]=\"color()\"\n [attr.stroke-width]=\"strokeWidth()\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n }\n <!-- A zero-length line with a round cap and a non-scaling stroke, which stays a\n circle however the drawing stretches; a `<circle>` stretched with it, into a\n 21 × 5px pill on the docs' full-width demo. Three times the line's width. -->\n @if (showTip() && tipPath(); as d) {\n <path\n class=\"wr-sparkline__tip\"\n [attr.d]=\"d\"\n fill=\"none\"\n [attr.stroke]=\"color()\"\n [attr.stroke-width]=\"strokeWidth() * 3\"\n stroke-linecap=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n }\n</svg>\n@if (markerAt(); as at) {\n <span\n #marker\n class=\"wr-sparkline__marker\"\n aria-hidden=\"true\"\n [style.left.px]=\"at.x\"\n [style.top.px]=\"at.y\"\n [style.background]=\"color()\"\n ></span>\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ngwr-charts-sparkline.mjs","names":[],"sources":["../../../projects/lib/charts/sparkline/sparkline.ts","../../../projects/lib/charts/sparkline/sparkline.html"],"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, ElementRef, ViewEncapsulation, computed, inject, input, viewChild } from '@angular/core';\n\nimport { useChartNumbers } from 'ngwr/charts/core';\nimport { useChartTooltip } from 'ngwr/popover';\n\n/**\n * Tiny inline trend line. SVG path drawn from `[data]: number[]` — no\n * axes, no labels, just the shape. Optional area fill + tip dot.\n *\n * @example\n * ```html\n * <wr-sparkline [data]=\"[12, 14, 9, 17, 21, 18, 23]\" />\n * <wr-sparkline [data]=\"prices\" [showArea]=\"true\" color=\"var(--wr-color-success)\" />\n * ```\n *\n * @see https://ngwr.dev/charts/sparkline\n */\n@Component({\n selector: 'wr-sparkline',\n templateUrl: './sparkline.html',\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-sparkline' },\n})\nexport class WrSparkline {\n /**\n * The values, left to right. Evenly spaced — a sparkline carries no x axis, so\n * pass an already-ordered series rather than points with their own timestamps.\n */\n readonly data = input<readonly number[]>([]);\n\n /**\n * Accessible name. A sparkline usually sits beside the number it summarises, where\n * announcing it again is noise — so it is `aria-hidden` by default and becomes a\n * named `role=\"img\"` only when a consumer says what it shows.\n */\n readonly ariaLabel = input<string | null>(null);\n\n /** Stroke colour. @default 'var(--wr-color-primary)' */\n readonly color = input<string>('var(--wr-color-primary)');\n\n /**\n * Line thickness in CSS pixels — `vector-effect=\"non-scaling-stroke\"` keeps it at\n * that width whatever the box is stretched to, so it is NOT in viewBox units.\n * @default 1.5\n */\n readonly strokeWidth = input(1.5, {\n transform: (v: unknown): number => Math.max(0.1, coerceNumberProperty(v, 1.5)),\n });\n\n /** Fill the area below the line, faintly (`--wr-sparkline-area-opacity`). @default false */\n readonly showArea = input(false, { transform: coerceBooleanProperty });\n\n /** Show a dot at the last data point. @default true */\n readonly showTip = input(true, { transform: coerceBooleanProperty });\n\n /** CSS width. @default '8rem' */\n readonly width = input<string>('8rem');\n\n /** CSS height. @default '2rem' */\n readonly height = input<string>('2rem');\n\n /**\n * Show a tooltip with the value of the point nearest the pointer, marking that\n * point, and named by `ariaLabel` when one is given. Pointer only. @default true\n */\n readonly tooltip = input(true, { transform: coerceBooleanProperty });\n\n /**\n * Writes the value in the tooltip. `null` uses `Intl.NumberFormat` in `LOCALE_ID`.\n */\n readonly valueFormat = input<((value: number) => string) | null>(null);\n\n /** The value as the tooltip writes it — in full, never compact, to `Intl`'s default precision. */\n private readonly numbers = useChartNumbers(this.valueFormat);\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly svg = viewChild<ElementRef<SVGSVGElement>>('svg');\n private readonly marker = viewChild<ElementRef<HTMLElement>>('marker');\n\n // Drawn in a 100×40 viewBox — scales smoothly to any CSS size.\n private readonly vbW = 100;\n private readonly vbH = 40;\n private readonly padding = 2;\n\n /**\n * The data as drawn. Non-finite values are dropped rather than scaled: every\n * `min`/`max` comparison against a NaN is false, so it survived into the scale and\n * `toFixed(2)` wrote the literal text `NaN` into the path `d` — invalid geometry,\n * and the line vanishes. The tooltip reads this list too, so the value it shows is\n * the one under the point it marks.\n */\n private readonly values = computed(() => this.data().filter(v => Number.isFinite(v)));\n\n /** Mapped `{ x, y }` points for the path. */\n protected readonly points = computed(() => {\n const data = this.values();\n if (data.length === 0) return [] as readonly { x: number; y: number }[];\n if (data.length === 1) return [{ x: this.vbW / 2, y: this.vbH / 2 }];\n\n let min = data[0];\n let max = data[0];\n for (const v of data) {\n if (v < min) min = v;\n if (v > max) max = v;\n }\n const pad = this.padding;\n const w = this.vbW - pad * 2;\n const h = this.vbH - pad * 2;\n // A series with no spread has no shape, and dividing by the old `|| 1` fallback\n // pinned every point to `pad + h` — the bottom edge — so a steady series at 500\n // read as rock bottom. Centred instead, which is what a lone datum already does.\n if (max === min) {\n return data.map((_, i) => ({ x: pad + (i / (data.length - 1)) * w, y: this.vbH / 2 }));\n }\n const span = max - min;\n return data.map((v, i) => ({\n x: pad + (i / (data.length - 1)) * w,\n y: pad + h - ((v - min) / span) * h,\n }));\n });\n\n /**\n * The line through every point. A lone point repeats itself: a subpath of one `M` is\n * never stroked, so a one-value sparkline with `showTip` off drew nothing at all, and\n * the round cap paints the repeat as a dot of the line's width.\n */\n protected readonly linePath = computed(() => {\n const points = this.points();\n const path = points.map((p, i) => `${i === 0 ? 'M' : 'L'} ${p.x.toFixed(2)} ${p.y.toFixed(2)}`).join(' ');\n return points.length === 1 ? `${path} L ${points[0].x.toFixed(2)} ${points[0].y.toFixed(2)}` : path;\n });\n\n protected readonly areaPath = computed(() => {\n const pts = this.points();\n if (pts.length < 2) return '';\n const baseY = this.vbH - this.padding;\n const start = `M ${pts[0].x.toFixed(2)} ${baseY}`;\n const line = pts.map(p => `L ${p.x.toFixed(2)} ${p.y.toFixed(2)}`).join(' ');\n const close = `L ${pts[pts.length - 1].x.toFixed(2)} ${baseY} Z`;\n return `${start} ${line} ${close}`;\n });\n\n /** A zero-length line at the last point, which a round cap paints as the tip dot. */\n protected readonly tipPath = computed(() => {\n const last = this.points().at(-1);\n return last ? `M ${last.x.toFixed(2)} ${last.y.toFixed(2)} h 0` : null;\n });\n\n protected readonly viewBox = `0 0 ${this.vbW} ${this.vbH}`;\n\n /**\n * One tooltip, pointing at the hovered point: above its marker, below it when there\n * is no room. The marker is the anchor element itself, drawn for the point the\n * tooltip reads — it renders before this runs, since both follow `tip.active()`.\n *\n * The chip sits INSIDE the drawing, over the stretch of line above the marker, so the\n * helper is also told which point any spot over the drawing reads: a pointer scrubbing\n * along the top of a sparkline would otherwise land on the chip and stop there.\n */\n protected readonly tip = useChartTooltip(\n this.tooltip,\n index => {\n const value = this.values()[index];\n const marker = this.marker()?.nativeElement;\n if (value === undefined || !marker) return null;\n return {\n datum: { label: this.ariaLabel() ?? undefined, value: this.numbers.value(value), color: this.color() },\n anchor: marker,\n };\n },\n (x, y) => {\n const svg = this.svg()?.nativeElement;\n if (!svg) return null;\n const box = svg.getBoundingClientRect();\n if (x < box.left || x > box.right || y < box.top || y > box.bottom) return null;\n return this.indexAt(x, box);\n }\n );\n\n /**\n * The marker's place in pixels from the host's padding edge, measured off the\n * DRAWING's box. An element rather than a `<circle>`: the drawing stretches to\n * any box with `preserveAspectRatio=\"none\"`, which would squash a circle into an\n * ellipse.\n *\n * Not percentages of the host, which is what it was: the host is only the\n * drawing's size until something stretches it — `width: 100%` on the element,\n * `display: block`, a column flex parent — while the drawing keeps its `width`.\n * Measured in Chromium, WebKit and Firefox on a 327px host round the default\n * 128px drawing, the marker for a point at 115px landed at 292px, out in empty\n * space with the chip above it. Read when a point is hovered, so the boxes are\n * laid out; `tip.active()` is never set on the server.\n */\n protected readonly markerAt = computed(() => {\n const index = this.tip.active();\n const point = index === null ? undefined : this.points()[index];\n const svg = this.svg()?.nativeElement;\n if (!point || !svg) return null;\n const host = this.host.nativeElement;\n const outer = host.getBoundingClientRect();\n const box = svg.getBoundingClientRect();\n return {\n x: box.left - outer.left - host.clientLeft + (point.x / this.vbW) * box.width,\n y: box.top - outer.top - host.clientTop + (point.y / this.vbH) * box.height,\n };\n });\n\n protected onPointerMove(event: MouseEvent): void {\n const index = this.indexAt(event.clientX, (event.currentTarget as Element).getBoundingClientRect());\n if (index !== null) this.tip.enter(index);\n }\n\n /**\n * The point nearest the pointer, along x only — the points are evenly spaced, so\n * that is a rounding rather than a search. A box with no width (nothing laid out\n * yet) answers nothing rather than a NaN index.\n */\n private indexAt(clientX: number, box: DOMRect): number | null {\n const count = this.points().length;\n if (count === 0 || box.width <= 0) return null;\n if (count === 1) return 0;\n const x = ((clientX - box.left) / box.width) * this.vbW;\n const step = (this.vbW - this.padding * 2) / (count - 1);\n return Math.min(count - 1, Math.max(0, Math.round((x - this.padding) / step)));\n }\n}\n","<svg\n #svg\n [attr.viewBox]=\"viewBox\"\n [style.width]=\"width()\"\n [style.height]=\"height()\"\n [attr.role]=\"ariaLabel() ? 'img' : null\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-hidden]=\"ariaLabel() ? null : 'true'\"\n preserveAspectRatio=\"none\"\n (mousemove)=\"onPointerMove($event)\"\n (mouseleave)=\"tip.leave($event)\"\n>\n @if (showArea() && areaPath()) {\n <!-- The fill's share of its colour is the stylesheet's, from `--wr-sparkline-area-opacity`. -->\n <path class=\"wr-sparkline__area\" [attr.d]=\"areaPath()\" [attr.fill]=\"color()\" stroke=\"none\" />\n }\n @if (linePath()) {\n <path\n class=\"wr-sparkline__line\"\n [attr.d]=\"linePath()\"\n fill=\"none\"\n [attr.stroke]=\"color()\"\n [attr.stroke-width]=\"strokeWidth()\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n }\n <!-- A zero-length line with a round cap and a non-scaling stroke, which stays a\n circle however the drawing stretches; a `<circle>` stretched with it, into a\n 21 × 5px pill on the docs' full-width demo. Three times the line's width. -->\n @if (showTip() && tipPath(); as d) {\n <path\n class=\"wr-sparkline__tip\"\n [attr.d]=\"d\"\n fill=\"none\"\n [attr.stroke]=\"color()\"\n [attr.stroke-width]=\"strokeWidth() * 3\"\n stroke-linecap=\"round\"\n vector-effect=\"non-scaling-stroke\"\n />\n }\n</svg>\n@if (markerAt(); as at) {\n <span\n #marker\n class=\"wr-sparkline__marker\"\n aria-hidden=\"true\"\n [style.left.px]=\"at.x\"\n [style.top.px]=\"at.y\"\n [style.background]=\"color()\"\n ></span>\n}\n"],"mappings":"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"}
@@ -0,0 +1,103 @@
1
+ import { ComponentHarness, HarnessPredicate } from "@angular/cdk/testing";
2
+ /**
3
+ * @license
4
+ *
5
+ * Use of this source code is governed by an MIT-style license that can be
6
+ * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
7
+ */
8
+ function declaration(style, property) {
9
+ const escaped = property.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&");
10
+ return new RegExp(`(?:^|;)\\s*${escaped}:\\s*([^;]+)`).exec(style)?.[1].trim() ?? null;
11
+ }
12
+ var TableRowHarness = class extends ComponentHarness {
13
+ static hostSelector = ".wr-chart-table tbody tr";
14
+ async read() {
15
+ const header = await this.locatorFor("th[scope=\"row\"]")();
16
+ const cells = await this.locatorForAll("td")();
17
+ return {
18
+ header: await header.text(),
19
+ cells: await Promise.all(cells.map((cell) => cell.text()))
20
+ };
21
+ }
22
+ };
23
+ var TileHarness = class extends ComponentHarness {
24
+ static hostSelector = ".wr-treemap-chart__tile";
25
+ async read() {
26
+ const host = await this.host();
27
+ const label = await this.locatorForOptional(".wr-treemap-chart__label")();
28
+ const value = await this.locatorForOptional(".wr-treemap-chart__value")();
29
+ const style = await host.getAttribute("style") ?? "";
30
+ const box = (property) => {
31
+ const written = declaration(style, property);
32
+ if (!written?.endsWith("%")) throw new Error(`WrTreemapChartHarness.getTiles(): no percentage for \`${property}\` on a tile (style: "${style}"). The component writes all four unconditionally, so its absence is the bug rather than a zero.`);
33
+ return Number.parseFloat(written);
34
+ };
35
+ const rect = {
36
+ start: box("inset-inline-start"),
37
+ top: box("top"),
38
+ width: box("width"),
39
+ height: box("height")
40
+ };
41
+ return {
42
+ label: label ? await label.text() : null,
43
+ value: value ? await value.text() : null,
44
+ group: await host.hasClass("wr-treemap-chart__tile--group"),
45
+ color: declaration(style, "--wr-treemap-chart-tile-color"),
46
+ box: rect
47
+ };
48
+ }
49
+ };
50
+ var WrTreemapChartHarness = class WrTreemapChartHarness extends ComponentHarness {
51
+ static hostSelector = "wr-treemap-chart";
52
+ static with(options = {}) {
53
+ return new HarnessPredicate(WrTreemapChartHarness, options).addOption("ariaLabel", options.ariaLabel, (harness, label) => HarnessPredicate.stringMatches(harness.getAccessibleName(), label)).addOption("tileLabel", options.tileLabel, async (harness, label) => {
54
+ for (const name of await harness.getLabels()) if (await HarnessPredicate.stringMatches(name, label)) return true;
55
+ return false;
56
+ });
57
+ }
58
+ async getAccessibleName() {
59
+ return (await this.locatorFor(".wr-treemap-chart__plot")()).getAttribute("aria-label");
60
+ }
61
+ async getTiles() {
62
+ const tiles = await this.locatorForAll(TileHarness)();
63
+ return Promise.all(tiles.map((tile) => tile.read()));
64
+ }
65
+ async getTileCount() {
66
+ return (await this.locatorForAll(".wr-treemap-chart__tile")()).length;
67
+ }
68
+ async getGroupCount() {
69
+ return (await this.locatorForAll(".wr-treemap-chart__tile--group")()).length;
70
+ }
71
+ async getLeafCount() {
72
+ return (await this.locatorForAll(".wr-treemap-chart__tile--leaf")()).length;
73
+ }
74
+ async getLabels() {
75
+ const labels = await this.locatorForAll(".wr-treemap-chart__label")();
76
+ return Promise.all(labels.map((label) => label.text()));
77
+ }
78
+ async hasDataTable() {
79
+ return await this.locatorForOptional(".wr-chart-table")() !== null;
80
+ }
81
+ async getTableColumns() {
82
+ await this.assertDataTable("getTableColumns");
83
+ const headings = await this.locatorForAll(".wr-chart-table thead th[scope=\"col\"]")();
84
+ return Promise.all(headings.map((heading) => heading.text()));
85
+ }
86
+ async getTableRows() {
87
+ await this.assertDataTable("getTableRows");
88
+ const rows = await this.locatorForAll(TableRowHarness)();
89
+ return Promise.all(rows.map((row) => row.read()));
90
+ }
91
+ async getPlotHeight() {
92
+ const style = await (await this.locatorFor(".wr-treemap-chart__plot")()).getAttribute("style") ?? "";
93
+ const written = declaration(style, "height");
94
+ if (!written?.endsWith("px")) throw new Error(`WrTreemapChartHarness.getPlotHeight(): no inline height on .wr-treemap-chart__plot (style: "${style}"). The component writes one unconditionally, so its absence is the bug rather than a zero.`);
95
+ return Number.parseFloat(written);
96
+ }
97
+ async assertDataTable(method) {
98
+ if (!await this.hasDataTable()) throw new Error(`WrTreemapChartHarness.${method}(): the chart renders no data table — \`dataTable\` is off. Ask hasDataTable() first.`);
99
+ }
100
+ };
101
+ export { WrTreemapChartHarness };
102
+
103
+ //# sourceMappingURL=ngwr-charts-treemap-chart-testing.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ngwr-charts-treemap-chart-testing.mjs","names":[],"sources":["../../../projects/lib/charts/treemap-chart/testing/wr-treemap-chart-harness.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 {\n WrTreemapChartHarnessFilters,\n WrTreemapChartTableRow,\n WrTreemapChartTile,\n WrTreemapChartTileBox,\n} from './types';\n\n/** One declaration of an inline `style` attribute, or `null` when the component wrote none. */\nfunction declaration(style: string, property: string): string | null {\n const escaped = property.replace(/[-/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n return new RegExp(`(?:^|;)\\\\s*${escaped}:\\\\s*([^;]+)`).exec(style)?.[1].trim() ?? null;\n}\n\n/**\n * One body row of the chart's data table, so its header and cells are read off the row\n * they sit in rather than matched up by position across the whole table.\n */\nclass TableRowHarness extends ComponentHarness {\n static hostSelector = '.wr-chart-table tbody tr';\n\n async read(): Promise<WrTreemapChartTableRow> {\n const header = await this.locatorFor('th[scope=\"row\"]')();\n const cells = await this.locatorForAll('td')();\n return { header: await header.text(), cells: await Promise.all(cells.map(cell => cell.text())) };\n }\n}\n\n/** One tile, so its name and figure are read off the tile they sit in. */\nclass TileHarness extends ComponentHarness {\n static hostSelector = '.wr-treemap-chart__tile';\n\n async read(): Promise<WrTreemapChartTile> {\n const host = await this.host();\n const label = await this.locatorForOptional('.wr-treemap-chart__label')();\n const value = await this.locatorForOptional('.wr-treemap-chart__value')();\n const style = (await host.getAttribute('style')) ?? '';\n const box = (property: string): number => {\n const written = declaration(style, property);\n if (!written?.endsWith('%')) {\n throw new Error(\n `WrTreemapChartHarness.getTiles(): no percentage for \\`${property}\\` on a tile (style: \"${style}\"). ` +\n 'The component writes all four unconditionally, so its absence is the bug rather than a zero.'\n );\n }\n return Number.parseFloat(written);\n };\n const rect: WrTreemapChartTileBox = {\n start: box('inset-inline-start'),\n top: box('top'),\n width: box('width'),\n height: box('height'),\n };\n return {\n label: label ? await label.text() : null,\n value: value ? await value.text() : null,\n group: await host.hasClass('wr-treemap-chart__tile--group'),\n color: declaration(style, '--wr-treemap-chart-tile-color'),\n box: rect,\n };\n }\n}\n\n/**\n * Test harness for `<wr-treemap-chart>`.\n *\n * **What it reads is what the component WROTE**: each tile's rectangle as the\n * percentages on its `style` attribute, its colour as the custom property beside them,\n * its name and figure as text, and the data table. Those are what the layout and the\n * data wiring produce, and what breaks when either does. jsdom lays nothing out, so a\n * name is read in full whether a browser would ellipsise it or not, and there is no\n * method for whether it was. Nor for whether a value fits: the stylesheet hides a value\n * wider than its tile by wrapping it out of sight, which takes a layout jsdom does not\n * have, so {@link getTiles} gives the text the component printed, fitting or not.\n *\n * **The layout is cut for the plot's measured size**, and jsdom measures nothing: in a\n * spec the chart cuts it for the width it assumes before measuring, 640 px, at its\n * `height`. So a spec can pin areas and order, which hold at any size, and should not\n * pin a tile's exact shape, which a browser's real width changes.\n *\n * **The tooltip is not opened from here.** It is pointer only, it renders into the\n * overlay container rather than the chart, and it says nothing the data table does not:\n * {@link getTableRows} reads the same path, value and share, which is where a keyboard\n * and a screen reader find them too.\n *\n * @example\n * ```ts\n * const chart = await loader.getHarness(WrTreemapChartHarness.with({ ariaLabel: 'Budget' }));\n *\n * expect(await chart.getLabels()).toContain('Engineering');\n * expect(await chart.getGroupCount()).toBe(2);\n * ```\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrTreemapChartHarness extends ComponentHarness {\n static hostSelector = 'wr-treemap-chart';\n\n /** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */\n static with(options: WrTreemapChartHarnessFilters = {}): HarnessPredicate<WrTreemapChartHarness> {\n return new HarnessPredicate(WrTreemapChartHarness, options)\n .addOption('ariaLabel', options.ariaLabel, (harness, label) =>\n HarnessPredicate.stringMatches(harness.getAccessibleName(), label)\n )\n .addOption('tileLabel', options.tileLabel, async (harness, label) => {\n for (const name of await harness.getLabels()) {\n if (await HarnessPredicate.stringMatches(name, label)) return true;\n }\n return false;\n });\n }\n\n /** The drawing's accessible name — the only thing about it a screen reader hears. */\n async getAccessibleName(): Promise<string | null> {\n return (await this.locatorFor('.wr-treemap-chart__plot')()).getAttribute('aria-label');\n }\n\n /**\n * Every tile drawn, parents before their children and siblings largest first: its name\n * and figure where it has room for them, whether it holds its children, its colour, and\n * its rectangle.\n *\n * A node with no area — no value, zero, negative — draws no tile, and is in the data\n * table all the same.\n */\n async getTiles(): Promise<WrTreemapChartTile[]> {\n const tiles = await this.locatorForAll(TileHarness)();\n return Promise.all(tiles.map(tile => tile.read()));\n }\n\n /** How many tiles were drawn, groups and leaves together. */\n async getTileCount(): Promise<number> {\n return (await this.locatorForAll('.wr-treemap-chart__tile')()).length;\n }\n\n /** How many tiles hold their children inside them. */\n async getGroupCount(): Promise<number> {\n return (await this.locatorForAll('.wr-treemap-chart__tile--group')()).length;\n }\n\n /** How many tiles hold nothing: leaves, and groups too small to draw their children in. */\n async getLeafCount(): Promise<number> {\n return (await this.locatorForAll('.wr-treemap-chart__tile--leaf')()).length;\n }\n\n /**\n * The names written on the tiles, in the order drawn — a group's in its strip, a leaf's\n * in its corner. A tile too small for its name writes none, and `showLabels` off writes\n * none at all.\n */\n async getLabels(): Promise<string[]> {\n const labels = await this.locatorForAll('.wr-treemap-chart__label')();\n return Promise.all(labels.map(label => label.text()));\n }\n\n /** Whether the hidden data table is rendered (`dataTable`). */\n async hasDataTable(): Promise<boolean> {\n return (await this.locatorForOptional('.wr-chart-table')()) !== null;\n }\n\n /**\n * The data table's column headings: the value's name (`valueLabel`) and the share's.\n *\n * Throws when the chart renders no table (`dataTable` off) rather than answering with no\n * columns.\n */\n async getTableColumns(): Promise<string[]> {\n await this.assertDataTable('getTableColumns');\n const headings = await this.locatorForAll('.wr-chart-table thead th[scope=\"col\"]')();\n return Promise.all(headings.map(heading => heading.text()));\n }\n\n /**\n * The data table's rows, one per node, parents before their children in the data's own\n * order: its path, its value and its share of the whole, as a screen reader walks them.\n * A node with no area has an empty share, and a leaf with no value an empty value too.\n *\n * Throws when the chart renders no table (`dataTable` off), for the reason\n * {@link getTableColumns} gives.\n */\n async getTableRows(): Promise<WrTreemapChartTableRow[]> {\n await this.assertDataTable('getTableRows');\n const rows = await this.locatorForAll(TableRowHarness)();\n return Promise.all(rows.map(row => row.read()));\n }\n\n /**\n * The plot's height in pixels — `height` as the component wrote it — read off the\n * `style` ATTRIBUTE of the plot rather than through `getCssValue()`, which answers from\n * the laid-out box and so agrees in jsdom and not in a browser.\n */\n async getPlotHeight(): Promise<number> {\n const style = (await (await this.locatorFor('.wr-treemap-chart__plot')()).getAttribute('style')) ?? '';\n const written = declaration(style, 'height');\n if (!written?.endsWith('px')) {\n throw new Error(\n `WrTreemapChartHarness.getPlotHeight(): no inline height on .wr-treemap-chart__plot (style: \"${style}\"). ` +\n 'The component writes one unconditionally, so its absence is the bug rather than a zero.'\n );\n }\n return Number.parseFloat(written);\n }\n\n private async assertDataTable(method: string): Promise<void> {\n if (!(await this.hasDataTable())) {\n throw new Error(\n `WrTreemapChartHarness.${method}(): the chart renders no data table — \\`dataTable\\` is off. Ask hasDataTable() first.`\n );\n }\n }\n}\n"],"mappings":"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"}