@kirbydesign/designsystem 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (552) hide show
  1. package/README.md +7 -0
  2. package/karma.conf.js +34 -0
  3. package/ng-package.json +32 -0
  4. package/ngcc.config.js +3 -0
  5. package/package.json +27 -0
  6. package/src/index.ts +1 -0
  7. package/src/lib/animation/kirby-animation.ts +12 -0
  8. package/src/lib/components/accordion/accordion-item.component.html +25 -0
  9. package/src/lib/components/accordion/accordion-item.component.scss +64 -0
  10. package/src/lib/components/accordion/accordion-item.component.spec.ts +52 -0
  11. package/src/lib/components/accordion/accordion-item.component.ts +27 -0
  12. package/src/lib/components/accordion/accordion.directive.ts +7 -0
  13. package/src/lib/components/accordion/index.ts +2 -0
  14. package/src/lib/components/angular-component-lib/utils.ts +43 -0
  15. package/src/lib/components/app/app.component.html +3 -0
  16. package/src/lib/components/app/app.component.scss +10 -0
  17. package/src/lib/components/app/app.component.spec.ts +52 -0
  18. package/src/lib/components/app/app.component.ts +50 -0
  19. package/src/lib/components/app/app.module.ts +12 -0
  20. package/src/lib/components/app/index.ts +2 -0
  21. package/src/lib/components/avatar/avatar.component.html +6 -0
  22. package/src/lib/components/avatar/avatar.component.scss +153 -0
  23. package/src/lib/components/avatar/avatar.component.spec.ts +207 -0
  24. package/src/lib/components/avatar/avatar.component.ts +32 -0
  25. package/src/lib/components/badge/badge.component.spec.ts +78 -0
  26. package/src/lib/components/button/button.component.html +1 -0
  27. package/src/lib/components/button/button.component.integration.spec.ts +576 -0
  28. package/src/lib/components/button/button.component.scss +286 -0
  29. package/src/lib/components/button/button.component.spec.ts +404 -0
  30. package/src/lib/components/button/button.component.ts +96 -0
  31. package/src/lib/components/calendar/calendar.component.html +49 -0
  32. package/src/lib/components/calendar/calendar.component.initialization.spec.ts +93 -0
  33. package/src/lib/components/calendar/calendar.component.scss +132 -0
  34. package/src/lib/components/calendar/calendar.component.spec.ts +470 -0
  35. package/src/lib/components/calendar/calendar.component.ts +513 -0
  36. package/src/lib/components/calendar/helpers/calendar-cell.model.ts +7 -0
  37. package/src/lib/components/calendar/helpers/calendar-options.model.ts +10 -0
  38. package/src/lib/components/calendar/helpers/calendar.helper.ts +108 -0
  39. package/src/lib/components/calendar/index.ts +2 -0
  40. package/src/lib/components/calendar/options/calendar-year-navigator-config.ts +4 -0
  41. package/src/lib/components/card/card-footer/card-footer.component.html +3 -0
  42. package/src/lib/components/card/card-footer/card-footer.component.scss +19 -0
  43. package/src/lib/components/card/card-footer/card-footer.component.ts +13 -0
  44. package/src/lib/components/card/card-header/card-header.component.html +5 -0
  45. package/src/lib/components/card/card-header/card-header.component.scss +63 -0
  46. package/src/lib/components/card/card-header/card-header.component.ts +20 -0
  47. package/src/lib/components/card/card.component.html +5 -0
  48. package/src/lib/components/card/card.component.scss +56 -0
  49. package/src/lib/components/card/card.component.spec.ts +81 -0
  50. package/src/lib/components/card/card.component.ts +95 -0
  51. package/src/lib/components/card/index.ts +3 -0
  52. package/src/lib/components/chart/chart-js/chart-js.service.integration.spec.ts +320 -0
  53. package/src/lib/components/chart/chart-js/chart-js.service.spec.ts +1004 -0
  54. package/src/lib/components/chart/chart-js/chart-js.service.ts +445 -0
  55. package/src/lib/components/chart/chart-js/chartjs-plugin-marker/chartjs-plugin-marker.ts +254 -0
  56. package/src/lib/components/chart/chart-js/configured-chart-js.ts +39 -0
  57. package/src/lib/components/chart/chart-js/test-utils.ts +171 -0
  58. package/src/lib/components/chart/chart.component.html +7 -0
  59. package/src/lib/components/chart/chart.component.scss +6 -0
  60. package/src/lib/components/chart/chart.component.spec.ts +188 -0
  61. package/src/lib/components/chart/chart.component.ts +148 -0
  62. package/src/lib/components/chart/chart.module.ts +11 -0
  63. package/src/lib/components/chart/chart.types.ts +34 -0
  64. package/src/lib/components/chart/configs/annotations.config.ts +36 -0
  65. package/src/lib/components/chart/configs/chart-config.service.spec.ts +21 -0
  66. package/src/lib/components/chart/configs/chart-config.service.ts +34 -0
  67. package/src/lib/components/chart/configs/global-defaults.config.ts +50 -0
  68. package/src/lib/components/chart/configs/interaction-functions-extensions.config.ts +19 -0
  69. package/src/lib/components/chart/configs/shared.utils.ts +28 -0
  70. package/src/lib/components/chart/configs/type.config.ts +214 -0
  71. package/src/lib/components/chart/index.ts +5 -0
  72. package/src/lib/components/chart-deprecated/chart-deprecated-helper.ts +25 -0
  73. package/src/lib/components/chart-deprecated/chart-deprecated-type.ts +10 -0
  74. package/src/lib/components/chart-deprecated/chart-deprecated.component.scss +3 -0
  75. package/src/lib/components/chart-deprecated/chart-deprecated.component.spec.ts +271 -0
  76. package/src/lib/components/chart-deprecated/chart-deprecated.component.ts +233 -0
  77. package/src/lib/components/chart-deprecated/index.ts +2 -0
  78. package/src/lib/components/chart-deprecated/options/activitygauge.ts +87 -0
  79. package/src/lib/components/chart-deprecated/options/areaspline.ts +95 -0
  80. package/src/lib/components/chart-deprecated/options/bar.ts +93 -0
  81. package/src/lib/components/chart-deprecated/options/column.ts +101 -0
  82. package/src/lib/components/chart-deprecated/options/donut.ts +118 -0
  83. package/src/lib/components/chart-deprecated/options/timeseries.ts +96 -0
  84. package/src/lib/components/checkbox/checkbox.component.html +10 -0
  85. package/src/lib/components/checkbox/checkbox.component.integration.spec.ts +59 -0
  86. package/src/lib/components/checkbox/checkbox.component.scss +130 -0
  87. package/src/lib/components/checkbox/checkbox.component.spec.ts +205 -0
  88. package/src/lib/components/checkbox/checkbox.component.ts +56 -0
  89. package/src/lib/components/chip/chip.component.html +1 -0
  90. package/src/lib/components/chip/chip.component.integration.spec.ts +111 -0
  91. package/src/lib/components/chip/chip.component.scss +49 -0
  92. package/src/lib/components/chip/chip.component.spec.ts +84 -0
  93. package/src/lib/components/chip/chip.component.ts +16 -0
  94. package/src/lib/components/divider/divider.component.html +1 -0
  95. package/src/lib/components/divider/divider.component.scss +22 -0
  96. package/src/lib/components/divider/divider.component.spec.ts +24 -0
  97. package/src/lib/components/divider/divider.component.ts +12 -0
  98. package/src/lib/components/dropdown/dropdown-popover.component.integration.spec.ts +177 -0
  99. package/src/lib/components/dropdown/dropdown-popover.component.spec.ts +1154 -0
  100. package/src/lib/components/dropdown/dropdown.component.html +42 -0
  101. package/src/lib/components/dropdown/dropdown.component.scss +142 -0
  102. package/src/lib/components/dropdown/dropdown.component.spec.ts +1215 -0
  103. package/src/lib/components/dropdown/dropdown.component.ts +538 -0
  104. package/src/lib/components/dropdown/dropdown.types.ts +10 -0
  105. package/src/lib/components/dropdown/keyboard-handler.service.ts +38 -0
  106. package/src/lib/components/empty-state/empty-state.component.html +10 -0
  107. package/src/lib/components/empty-state/empty-state.component.integration.spec.ts +110 -0
  108. package/src/lib/components/empty-state/empty-state.component.scss +50 -0
  109. package/src/lib/components/empty-state/empty-state.component.spec.ts +40 -0
  110. package/src/lib/components/empty-state/empty-state.component.ts +50 -0
  111. package/src/lib/components/fab-sheet/fab-sheet.component.html +13 -0
  112. package/src/lib/components/fab-sheet/fab-sheet.component.scss +67 -0
  113. package/src/lib/components/fab-sheet/fab-sheet.component.spec.ts +29 -0
  114. package/src/lib/components/fab-sheet/fab-sheet.component.ts +100 -0
  115. package/src/lib/components/flag/flag.component.scss +40 -0
  116. package/src/lib/components/flag/flag.component.spec.ts +152 -0
  117. package/src/lib/components/flag/flag.component.ts +18 -0
  118. package/src/lib/components/form-field/_form-field-inputs.shared.scss +62 -0
  119. package/src/lib/components/form-field/directives/date/date-input.directive.spec.ts +127 -0
  120. package/src/lib/components/form-field/directives/date/date-input.directive.ts +94 -0
  121. package/src/lib/components/form-field/directives/decimal-mask/decimal-mask.directive.spec.ts +231 -0
  122. package/src/lib/components/form-field/directives/decimal-mask/decimal-mask.directive.ts +113 -0
  123. package/src/lib/components/form-field/form-field-message/form-field-message.component.html +1 -0
  124. package/src/lib/components/form-field/form-field-message/form-field-message.component.scss +11 -0
  125. package/src/lib/components/form-field/form-field-message/form-field-message.component.ts +12 -0
  126. package/src/lib/components/form-field/form-field.component.html +39 -0
  127. package/src/lib/components/form-field/form-field.component.scss +43 -0
  128. package/src/lib/components/form-field/form-field.component.spec.ts +521 -0
  129. package/src/lib/components/form-field/form-field.component.ts +141 -0
  130. package/src/lib/components/form-field/index.ts +7 -0
  131. package/src/lib/components/form-field/input/input.component.integration.spec.ts +83 -0
  132. package/src/lib/components/form-field/input/input.component.scss +54 -0
  133. package/src/lib/components/form-field/input/input.component.spec.ts +159 -0
  134. package/src/lib/components/form-field/input/input.component.ts +91 -0
  135. package/src/lib/components/form-field/input-counter/input-counter.component.html +1 -0
  136. package/src/lib/components/form-field/input-counter/input-counter.component.spec.ts +184 -0
  137. package/src/lib/components/form-field/input-counter/input-counter.component.ts +41 -0
  138. package/src/lib/components/form-field/textarea/textarea.component.html +2 -0
  139. package/src/lib/components/form-field/textarea/textarea.component.scss +11 -0
  140. package/src/lib/components/form-field/textarea/textarea.component.spec.ts +100 -0
  141. package/src/lib/components/form-field/textarea/textarea.component.ts +64 -0
  142. package/src/lib/components/grid/breakpoint-helper.service.ts +27 -0
  143. package/src/lib/components/grid/grid-card-configuration.ts +7 -0
  144. package/src/lib/components/grid/grid.component.html +6 -0
  145. package/src/lib/components/grid/grid.component.scss +26 -0
  146. package/src/lib/components/grid/grid.component.ts +106 -0
  147. package/src/lib/components/icon/icon-registry.service.spec.ts +107 -0
  148. package/src/lib/components/icon/icon-registry.service.ts +39 -0
  149. package/src/lib/components/icon/icon-settings.ts +8 -0
  150. package/src/lib/components/icon/icon.component.html +1 -0
  151. package/src/lib/components/icon/icon.component.scss +47 -0
  152. package/src/lib/components/icon/icon.component.spec.ts +254 -0
  153. package/src/lib/components/icon/icon.component.ts +89 -0
  154. package/src/lib/components/icon/icon.module.ts +11 -0
  155. package/src/lib/components/icon/index.ts +5 -0
  156. package/src/lib/components/icon/kirby-icon-settings.ts +65 -0
  157. package/src/lib/components/icon/readme.md +16 -0
  158. package/src/lib/components/icon/selection.json +1776 -0
  159. package/src/lib/components/index.ts +67 -0
  160. package/src/lib/components/item/_item.utils.scss +36 -0
  161. package/src/lib/components/item/index.ts +3 -0
  162. package/src/lib/components/item/item.component.html +16 -0
  163. package/src/lib/components/item/item.component.integration.spec.ts +64 -0
  164. package/src/lib/components/item/item.component.scss +156 -0
  165. package/src/lib/components/item/item.component.spec.ts +85 -0
  166. package/src/lib/components/item/item.component.ts +37 -0
  167. package/src/lib/components/item/item.module.ts +14 -0
  168. package/src/lib/components/item/label/label.component.html +3 -0
  169. package/src/lib/components/item/label/label.component.scss +36 -0
  170. package/src/lib/components/item/label/label.component.spec.ts +23 -0
  171. package/src/lib/components/item/label/label.component.ts +16 -0
  172. package/src/lib/components/item-group/item-group.component.html +1 -0
  173. package/src/lib/components/item-group/item-group.component.scss +3 -0
  174. package/src/lib/components/item-group/item-group.component.spec.ts +42 -0
  175. package/src/lib/components/item-group/item-group.component.ts +10 -0
  176. package/src/lib/components/item-sliding/index.ts +2 -0
  177. package/src/lib/components/item-sliding/item-sliding.component.html +20 -0
  178. package/src/lib/components/item-sliding/item-sliding.component.scss +9 -0
  179. package/src/lib/components/item-sliding/item-sliding.component.spec.ts +174 -0
  180. package/src/lib/components/item-sliding/item-sliding.component.ts +23 -0
  181. package/src/lib/components/item-sliding/item-sliding.shared.scss +18 -0
  182. package/src/lib/components/item-sliding/item-sliding.types.ts +13 -0
  183. package/src/lib/components/list/directives/infinite-scroll.directive.spec.ts +131 -0
  184. package/src/lib/components/list/directives/infinite-scroll.directive.ts +137 -0
  185. package/src/lib/components/list/directives/list-item-color.directive.ts +27 -0
  186. package/src/lib/components/list/directives/scroll.model.ts +5 -0
  187. package/src/lib/components/list/helpers/list-helper.spec.ts +109 -0
  188. package/src/lib/components/list/helpers/list-helper.ts +19 -0
  189. package/src/lib/components/list/index.ts +21 -0
  190. package/src/lib/components/list/list-experimental/list-experimental.component.html +4 -0
  191. package/src/lib/components/list/list-experimental/list-experimental.component.scss +6 -0
  192. package/src/lib/components/list/list-experimental/list-experimental.component.spec.ts +112 -0
  193. package/src/lib/components/list/list-experimental/list-experimental.component.ts +21 -0
  194. package/src/lib/components/list/list-header/list-header.component.html +1 -0
  195. package/src/lib/components/list/list-header/list-header.component.scss +10 -0
  196. package/src/lib/components/list/list-header/list-header.component.spec.ts +24 -0
  197. package/src/lib/components/list/list-header/list-header.component.ts +11 -0
  198. package/src/lib/components/list/list-item/list-item.component.html +39 -0
  199. package/src/lib/components/list/list-item/list-item.component.scss +13 -0
  200. package/src/lib/components/list/list-item/list-item.component.ts +144 -0
  201. package/src/lib/components/list/list-section-header/list-section-header.component.html +3 -0
  202. package/src/lib/components/list/list-section-header/list-section-header.component.spec.ts +24 -0
  203. package/src/lib/components/list/list-section-header/list-section-header.component.ts +13 -0
  204. package/src/lib/components/list/list-swipe-action.ts +2 -0
  205. package/src/lib/components/list/list-swipe-action.type.ts +23 -0
  206. package/src/lib/components/list/list.component.html +65 -0
  207. package/src/lib/components/list/list.component.integration.spec.ts +177 -0
  208. package/src/lib/components/list/list.component.scss +243 -0
  209. package/src/lib/components/list/list.component.spec.ts +219 -0
  210. package/src/lib/components/list/list.component.ts +213 -0
  211. package/src/lib/components/list/list.directive.ts +21 -0
  212. package/src/lib/components/list/list.event.ts +8 -0
  213. package/src/lib/components/list/list.module.ts +47 -0
  214. package/src/lib/components/list/pipes/group-by.pipe.spec.ts +71 -0
  215. package/src/lib/components/list/pipes/group-by.pipe.ts +34 -0
  216. package/src/lib/components/loading-overlay/index.ts +2 -0
  217. package/src/lib/components/loading-overlay/loading-overlay.component.html +8 -0
  218. package/src/lib/components/loading-overlay/loading-overlay.component.scss +37 -0
  219. package/src/lib/components/loading-overlay/loading-overlay.component.ts +12 -0
  220. package/src/lib/components/loading-overlay/loading-overlay.service.ts +44 -0
  221. package/src/lib/components/modal/action-sheet/action-sheet.component.html +24 -0
  222. package/src/lib/components/modal/action-sheet/action-sheet.component.scss +47 -0
  223. package/src/lib/components/modal/action-sheet/action-sheet.component.spec.ts +153 -0
  224. package/src/lib/components/modal/action-sheet/action-sheet.component.ts +27 -0
  225. package/src/lib/components/modal/action-sheet/config/action-sheet-config.ts +8 -0
  226. package/src/lib/components/modal/action-sheet/config/action-sheet-item.ts +4 -0
  227. package/src/lib/components/modal/alert/alert.component.html +29 -0
  228. package/src/lib/components/modal/alert/alert.component.scss +21 -0
  229. package/src/lib/components/modal/alert/alert.component.spec.ts +104 -0
  230. package/src/lib/components/modal/alert/alert.component.ts +67 -0
  231. package/src/lib/components/modal/alert/config/alert-config.ts +19 -0
  232. package/src/lib/components/modal/footer/modal-footer.component.html +3 -0
  233. package/src/lib/components/modal/footer/modal-footer.component.scss +57 -0
  234. package/src/lib/components/modal/footer/modal-footer.component.spec.ts +209 -0
  235. package/src/lib/components/modal/footer/modal-footer.component.ts +17 -0
  236. package/src/lib/components/modal/index.ts +9 -0
  237. package/src/lib/components/modal/modal-wrapper/compact/modal-compact-wrapper.component.html +3 -0
  238. package/src/lib/components/modal/modal-wrapper/compact/modal-compact-wrapper.component.scss +8 -0
  239. package/src/lib/components/modal/modal-wrapper/compact/modal-compact-wrapper.component.ts +79 -0
  240. package/src/lib/components/modal/modal-wrapper/config/drawer-supplementary-action.ts +4 -0
  241. package/src/lib/components/modal/modal-wrapper/config/modal-config.helper.ts +3 -0
  242. package/src/lib/components/modal/modal-wrapper/config/modal-config.ts +22 -0
  243. package/src/lib/components/modal/modal-wrapper/modal-wrapper.component.html +43 -0
  244. package/src/lib/components/modal/modal-wrapper/modal-wrapper.component.scss +159 -0
  245. package/src/lib/components/modal/modal-wrapper/modal-wrapper.component.spec.ts +942 -0
  246. package/src/lib/components/modal/modal-wrapper/modal-wrapper.component.ts +587 -0
  247. package/src/lib/components/modal/modal-wrapper/modal-wrapper.testbuilder.ts +155 -0
  248. package/src/lib/components/modal/services/action-sheet.helper.spec.ts +86 -0
  249. package/src/lib/components/modal/services/action-sheet.helper.ts +47 -0
  250. package/src/lib/components/modal/services/alert.helper.spec.ts +89 -0
  251. package/src/lib/components/modal/services/alert.helper.ts +57 -0
  252. package/src/lib/components/modal/services/modal-animation-builder.service.ts +276 -0
  253. package/src/lib/components/modal/services/modal-navigation.service.spec.ts +543 -0
  254. package/src/lib/components/modal/services/modal-navigation.service.ts +331 -0
  255. package/src/lib/components/modal/services/modal.controller.spec.ts +212 -0
  256. package/src/lib/components/modal/services/modal.controller.ts +194 -0
  257. package/src/lib/components/modal/services/modal.helper.spec.ts +828 -0
  258. package/src/lib/components/modal/services/modal.helper.ts +128 -0
  259. package/src/lib/components/modal/services/modal.interfaces.ts +28 -0
  260. package/src/lib/components/page/index.ts +13 -0
  261. package/src/lib/components/page/page-footer/page-footer.component.html +3 -0
  262. package/src/lib/components/page/page-footer/page-footer.component.scss +23 -0
  263. package/src/lib/components/page/page-footer/page-footer.component.spec.ts +52 -0
  264. package/src/lib/components/page/page-footer/page-footer.component.ts +46 -0
  265. package/src/lib/components/page/page.component.html +101 -0
  266. package/src/lib/components/page/page.component.scss +141 -0
  267. package/src/lib/components/page/page.component.spec.ts +224 -0
  268. package/src/lib/components/page/page.component.ts +415 -0
  269. package/src/lib/components/page/page.module.ts +52 -0
  270. package/src/lib/components/popover/popover.component.scss +26 -0
  271. package/src/lib/components/popover/popover.component.spec.ts +0 -0
  272. package/src/lib/components/popover/popover.component.ts +221 -0
  273. package/src/lib/components/progress-circle/progress-circle-ring.component.scss +22 -0
  274. package/src/lib/components/progress-circle/progress-circle-ring.component.spec.ts +143 -0
  275. package/src/lib/components/progress-circle/progress-circle-ring.component.svg +23 -0
  276. package/src/lib/components/progress-circle/progress-circle-ring.component.ts +42 -0
  277. package/src/lib/components/progress-circle/progress-circle.component.html +11 -0
  278. package/src/lib/components/progress-circle/progress-circle.component.scss +28 -0
  279. package/src/lib/components/progress-circle/progress-circle.component.spec.ts +339 -0
  280. package/src/lib/components/progress-circle/progress-circle.component.ts +96 -0
  281. package/src/lib/components/radio/index.ts +2 -0
  282. package/src/lib/components/radio/radio-group/radio-group.component.html +24 -0
  283. package/src/lib/components/radio/radio-group/radio-group.component.spec.ts +1328 -0
  284. package/src/lib/components/radio/radio-group/radio-group.component.ts +272 -0
  285. package/src/lib/components/radio/radio.component.html +9 -0
  286. package/src/lib/components/radio/radio.component.integration.spec.ts +93 -0
  287. package/src/lib/components/radio/radio.component.scss +133 -0
  288. package/src/lib/components/radio/radio.component.spec.ts +244 -0
  289. package/src/lib/components/radio/radio.component.ts +50 -0
  290. package/src/lib/components/range/range.component.html +16 -0
  291. package/src/lib/components/range/range.component.scss +81 -0
  292. package/src/lib/components/range/range.component.ts +105 -0
  293. package/src/lib/components/reorder-list/index.ts +3 -0
  294. package/src/lib/components/reorder-list/reorder-event.ts +17 -0
  295. package/src/lib/components/reorder-list/reorder-list.component.html +30 -0
  296. package/src/lib/components/reorder-list/reorder-list.component.scss +90 -0
  297. package/src/lib/components/reorder-list/reorder-list.component.spec.ts +123 -0
  298. package/src/lib/components/reorder-list/reorder-list.component.ts +86 -0
  299. package/src/lib/components/router-outlet/index.ts +5 -0
  300. package/src/lib/components/router-outlet/router-outlet.component.html +6 -0
  301. package/src/lib/components/router-outlet/router-outlet.component.scss +13 -0
  302. package/src/lib/components/router-outlet/router-outlet.component.spec.ts +28 -0
  303. package/src/lib/components/router-outlet/router-outlet.component.ts +11 -0
  304. package/src/lib/components/router-outlet/router-outlet.module.ts +12 -0
  305. package/src/lib/components/section-header/_section-header.utils.scss +34 -0
  306. package/src/lib/components/section-header/section-header.component.html +3 -0
  307. package/src/lib/components/section-header/section-header.component.scss +15 -0
  308. package/src/lib/components/section-header/section-header.component.spec.ts +59 -0
  309. package/src/lib/components/section-header/section-header.component.ts +9 -0
  310. package/src/lib/components/section-header/section-header.integration.spec.ts +67 -0
  311. package/src/lib/components/segmented-control/segment-item.ts +18 -0
  312. package/src/lib/components/segmented-control/segmented-control.component.html +39 -0
  313. package/src/lib/components/segmented-control/segmented-control.component.scss +84 -0
  314. package/src/lib/components/segmented-control/segmented-control.component.spec.ts +247 -0
  315. package/src/lib/components/segmented-control/segmented-control.component.ts +96 -0
  316. package/src/lib/components/shared/component-configuration.ts +6 -0
  317. package/src/lib/components/shared/component-loader.directive.ts +42 -0
  318. package/src/lib/components/shared/dynamic-component.ts +3 -0
  319. package/src/lib/components/shared/index.ts +9 -0
  320. package/src/lib/components/shared/resize-observer/resize-observer.factory.ts +20 -0
  321. package/src/lib/components/shared/resize-observer/resize-observer.service.ts +65 -0
  322. package/src/lib/components/shared/resize-observer/types/resize-observer-callback.ts +7 -0
  323. package/src/lib/components/shared/resize-observer/types/resize-observer-entry.ts +14 -0
  324. package/src/lib/components/shared/resize-observer/types/resize-observer.ts +17 -0
  325. package/src/lib/components/slide-button/slide-button.component.html +14 -0
  326. package/src/lib/components/slide-button/slide-button.component.scss +81 -0
  327. package/src/lib/components/slide-button/slide-button.component.shared.scss +12 -0
  328. package/src/lib/components/slide-button/slide-button.component.spec.ts +75 -0
  329. package/src/lib/components/slide-button/slide-button.component.ts +81 -0
  330. package/src/lib/components/slides/slides.component.spec.ts +76 -0
  331. package/src/lib/components/slides/slides.component.ts +57 -0
  332. package/src/lib/components/spinner/index.ts +2 -0
  333. package/src/lib/components/spinner/spinner.component.html +4 -0
  334. package/src/lib/components/spinner/spinner.component.scss +37 -0
  335. package/src/lib/components/spinner/spinner.component.ts +13 -0
  336. package/src/lib/components/spinner/spinner.module.ts +12 -0
  337. package/src/lib/components/stock-chart-deprecated/index.ts +2 -0
  338. package/src/lib/components/stock-chart-deprecated/options/stock-chart-deprecated-options.ts +220 -0
  339. package/src/lib/components/stock-chart-deprecated/stock-chart-deprecated.component.scss +3 -0
  340. package/src/lib/components/stock-chart-deprecated/stock-chart-deprecated.component.spec.ts +32 -0
  341. package/src/lib/components/stock-chart-deprecated/stock-chart-deprecated.component.ts +92 -0
  342. package/src/lib/components/tabs/index.ts +5 -0
  343. package/src/lib/components/tabs/tab-button/tab-button.component.html +13 -0
  344. package/src/lib/components/tabs/tab-button/tab-button.component.scss +48 -0
  345. package/src/lib/components/tabs/tab-button/tab-button.component.spec.ts +24 -0
  346. package/src/lib/components/tabs/tab-button/tab-button.component.ts +47 -0
  347. package/src/lib/components/tabs/tab-button/tab-button.events.ts +1 -0
  348. package/src/lib/components/tabs/tabs.component.html +5 -0
  349. package/src/lib/components/tabs/tabs.component.scss +52 -0
  350. package/src/lib/components/tabs/tabs.component.spec.ts +125 -0
  351. package/src/lib/components/tabs/tabs.component.ts +21 -0
  352. package/src/lib/components/tabs/tabs.module.ts +16 -0
  353. package/src/lib/components/tabs/tabs.service.ts +17 -0
  354. package/src/lib/components/toast/config/toast-config.ts +8 -0
  355. package/src/lib/components/toast/index.ts +2 -0
  356. package/src/lib/components/toast/services/toast.controller.ts +18 -0
  357. package/src/lib/components/toast/services/toast.helper.spec.ts +89 -0
  358. package/src/lib/components/toast/services/toast.helper.ts +39 -0
  359. package/src/lib/components/toggle/toggle.component.html +5 -0
  360. package/src/lib/components/toggle/toggle.component.scss +5 -0
  361. package/src/lib/components/toggle/toggle.component.spec.ts +62 -0
  362. package/src/lib/components/toggle/toggle.component.ts +17 -0
  363. package/src/lib/components/toggle-button/index.ts +2 -0
  364. package/src/lib/components/toggle-button/toggle-button.component.html +6 -0
  365. package/src/lib/components/toggle-button/toggle-button.component.spec.ts +23 -0
  366. package/src/lib/components/toggle-button/toggle-button.component.ts +24 -0
  367. package/src/lib/components/toggle-button/toggle-button.module.ts +13 -0
  368. package/src/lib/components/web-component-proxies.component.ts +25 -0
  369. package/src/lib/custom-elements-initializer.ts +19 -0
  370. package/src/lib/directives/element-as-button/element-as-button.directive.spec.ts +31 -0
  371. package/src/lib/directives/element-as-button/element-as-button.directive.ts +26 -0
  372. package/src/lib/directives/fit-heading/fit-heading.directive.ts +131 -0
  373. package/src/lib/directives/fit-heading/fit-heading.module.ts +9 -0
  374. package/src/lib/directives/index.ts +9 -0
  375. package/src/lib/directives/key-handler/key-handler.directive.ts +20 -0
  376. package/src/lib/directives/modal-router-link/modal-router-link.directive.ts +24 -0
  377. package/src/lib/directives/theme-color/theme-color.directive.ts +117 -0
  378. package/src/lib/helpers/color-helper.styles.ts +193 -0
  379. package/src/lib/helpers/color-helper.ts +1 -0
  380. package/src/lib/helpers/deep-copy.ts +13 -0
  381. package/src/lib/helpers/design-token-helper.styles.ts +78 -0
  382. package/src/lib/helpers/design-token-helper.ts +6 -0
  383. package/src/lib/helpers/element-has-ancestor.ts +28 -0
  384. package/src/lib/helpers/index.ts +8 -0
  385. package/src/lib/helpers/line-clamp-helper.ts +28 -0
  386. package/src/lib/helpers/merge-deep.spec.ts +11 -0
  387. package/src/lib/helpers/merge-deep.ts +41 -0
  388. package/src/lib/helpers/platform.service.ts +22 -0
  389. package/src/lib/helpers/string-helper.ts +6 -0
  390. package/src/lib/helpers/theme-color.type.ts +1 -0
  391. package/src/lib/helpers/unique-id-generator.helper.spec.ts +58 -0
  392. package/src/lib/helpers/unique-id-generator.helper.ts +19 -0
  393. package/src/lib/icons/svg/QR.svg +7 -0
  394. package/src/lib/icons/svg/accounts-outline.svg +9 -0
  395. package/src/lib/icons/svg/accounts.svg +9 -0
  396. package/src/lib/icons/svg/add.svg +7 -0
  397. package/src/lib/icons/svg/arrow-back.svg +7 -0
  398. package/src/lib/icons/svg/arrow-down.svg +7 -0
  399. package/src/lib/icons/svg/arrow-more.svg +7 -0
  400. package/src/lib/icons/svg/arrow-up.svg +7 -0
  401. package/src/lib/icons/svg/attach.svg +7 -0
  402. package/src/lib/icons/svg/backspace.svg +9 -0
  403. package/src/lib/icons/svg/calendar.svg +7 -0
  404. package/src/lib/icons/svg/camera.svg +9 -0
  405. package/src/lib/icons/svg/checkbox-outline.svg +7 -0
  406. package/src/lib/icons/svg/checkbox.svg +7 -0
  407. package/src/lib/icons/svg/checkmark-selected.svg +3 -0
  408. package/src/lib/icons/svg/clock.svg +7 -0
  409. package/src/lib/icons/svg/close.svg +7 -0
  410. package/src/lib/icons/svg/cog.svg +7 -0
  411. package/src/lib/icons/svg/copy.svg +9 -0
  412. package/src/lib/icons/svg/edit.svg +7 -0
  413. package/src/lib/icons/svg/filter.svg +7 -0
  414. package/src/lib/icons/svg/flag.svg +9 -0
  415. package/src/lib/icons/svg/flash-off.svg +7 -0
  416. package/src/lib/icons/svg/flash.svg +7 -0
  417. package/src/lib/icons/svg/foreign-payment.svg +7 -0
  418. package/src/lib/icons/svg/help.svg +7 -0
  419. package/src/lib/icons/svg/home.svg +5 -0
  420. package/src/lib/icons/svg/inbox-outline.svg +9 -0
  421. package/src/lib/icons/svg/inbox.svg +9 -0
  422. package/src/lib/icons/svg/information.svg +9 -0
  423. package/src/lib/icons/svg/investment.svg +5 -0
  424. package/src/lib/icons/svg/kirby.svg +3 -0
  425. package/src/lib/icons/svg/link.svg +7 -0
  426. package/src/lib/icons/svg/log-out.svg +7 -0
  427. package/src/lib/icons/svg/menu-outline.svg +9 -0
  428. package/src/lib/icons/svg/menu.svg +9 -0
  429. package/src/lib/icons/svg/misc.svg +5 -0
  430. package/src/lib/icons/svg/moneybag.svg +7 -0
  431. package/src/lib/icons/svg/more.svg +5 -0
  432. package/src/lib/icons/svg/move.svg +7 -0
  433. package/src/lib/icons/svg/payment-card.svg +6 -0
  434. package/src/lib/icons/svg/pension.svg +7 -0
  435. package/src/lib/icons/svg/person-outline.svg +9 -0
  436. package/src/lib/icons/svg/person.svg +9 -0
  437. package/src/lib/icons/svg/remove.svg +6 -0
  438. package/src/lib/icons/svg/reorder.svg +9 -0
  439. package/src/lib/icons/svg/search.svg +7 -0
  440. package/src/lib/icons/svg/share.svg +7 -0
  441. package/src/lib/icons/svg/sort.svg +7 -0
  442. package/src/lib/icons/svg/support.svg +9 -0
  443. package/src/lib/icons/svg/swap.svg +7 -0
  444. package/src/lib/icons/svg/trash.svg +7 -0
  445. package/src/lib/icons/svg/unsubscribe.svg +7 -0
  446. package/src/lib/icons/svg/verify.svg +7 -0
  447. package/src/lib/icons/svg/warning.svg +7 -0
  448. package/src/lib/icons/svg/write-message.svg +7 -0
  449. package/src/lib/index.ts +8 -0
  450. package/src/lib/kirby.module.spec.ts +20 -0
  451. package/src/lib/kirby.module.ts +219 -0
  452. package/src/lib/polyfills/intersection-observer-polyfill-loader.js +14 -0
  453. package/src/lib/polyfills/intersection-observer-polyfill-loader.min.js +1 -0
  454. package/src/lib/polyfills/intersection-observer-polyfill.js +2 -0
  455. package/src/lib/polyfills/intersection-observer-polyfill.min.js +1 -0
  456. package/src/lib/polyfills/resize-observer-polyfill-loader.js +14 -0
  457. package/src/lib/polyfills/resize-observer-polyfill-loader.min.js +1 -0
  458. package/src/lib/polyfills/resize-observer-polyfill.js +2 -0
  459. package/src/lib/polyfills/resize-observer-polyfill.min.js +1 -0
  460. package/src/lib/scss/link.spec.ts +47 -0
  461. package/src/lib/scss/scss-helper.ts +8 -0
  462. package/src/lib/scss/typography.spec.ts +241 -0
  463. package/src/lib/testing/element-css-custom-matchers.d.ts +7 -0
  464. package/src/lib/testing/element-css-custom-matchers.ts +139 -0
  465. package/src/lib/testing/styles.scss +13 -0
  466. package/src/lib/testing/test-helper.ts +158 -0
  467. package/src/lib/types/index.ts +1 -0
  468. package/src/lib/types/window-ref.ts +10 -0
  469. package/src/test.ts +34 -0
  470. package/src/typings.test.d.ts +1 -0
  471. package/testing-base/ng-package.json +3 -0
  472. package/testing-base/src/lib/components/index.ts +66 -0
  473. package/testing-base/src/lib/components/mock.accordion-item.component.ts +21 -0
  474. package/testing-base/src/lib/components/mock.action-sheet.component.ts +27 -0
  475. package/testing-base/src/lib/components/mock.app.component.ts +18 -0
  476. package/testing-base/src/lib/components/mock.avatar.component.ts +38 -0
  477. package/testing-base/src/lib/components/mock.badge.component.ts +20 -0
  478. package/testing-base/src/lib/components/mock.button.component.ts +26 -0
  479. package/testing-base/src/lib/components/mock.calendar.component.ts +36 -0
  480. package/testing-base/src/lib/components/mock.card-footer.component.ts +18 -0
  481. package/testing-base/src/lib/components/mock.card-header.component.ts +23 -0
  482. package/testing-base/src/lib/components/mock.card.component.ts +25 -0
  483. package/testing-base/src/lib/components/mock.chart-deprecated.component.ts +28 -0
  484. package/testing-base/src/lib/components/mock.chart.component.ts +36 -0
  485. package/testing-base/src/lib/components/mock.checkbox.component.ts +26 -0
  486. package/testing-base/src/lib/components/mock.chip.component.ts +21 -0
  487. package/testing-base/src/lib/components/mock.divider.component.ts +20 -0
  488. package/testing-base/src/lib/components/mock.dropdown.component.ts +32 -0
  489. package/testing-base/src/lib/components/mock.empty-state.component.ts +23 -0
  490. package/testing-base/src/lib/components/mock.fab-sheet.component.ts +21 -0
  491. package/testing-base/src/lib/components/mock.flag.component.ts +21 -0
  492. package/testing-base/src/lib/components/mock.form-field-message.component.ts +21 -0
  493. package/testing-base/src/lib/components/mock.form-field.component.ts +23 -0
  494. package/testing-base/src/lib/components/mock.grid.component.ts +21 -0
  495. package/testing-base/src/lib/components/mock.icon.component.ts +22 -0
  496. package/testing-base/src/lib/components/mock.input-counter.component.ts +24 -0
  497. package/testing-base/src/lib/components/mock.input.component.ts +29 -0
  498. package/testing-base/src/lib/components/mock.item-group.component.ts +18 -0
  499. package/testing-base/src/lib/components/mock.item-sliding.component.ts +21 -0
  500. package/testing-base/src/lib/components/mock.item.component.ts +24 -0
  501. package/testing-base/src/lib/components/mock.label.component.ts +20 -0
  502. package/testing-base/src/lib/components/mock.list-experimental.component.ts +18 -0
  503. package/testing-base/src/lib/components/mock.list-header.component.ts +18 -0
  504. package/testing-base/src/lib/components/mock.list-item.component.ts +33 -0
  505. package/testing-base/src/lib/components/mock.list-section-header.component.ts +20 -0
  506. package/testing-base/src/lib/components/mock.list.component.ts +39 -0
  507. package/testing-base/src/lib/components/mock.loading-overlay.component.ts +21 -0
  508. package/testing-base/src/lib/components/mock.modal-footer.component.ts +21 -0
  509. package/testing-base/src/lib/components/mock.page-footer.component.ts +20 -0
  510. package/testing-base/src/lib/components/mock.page.component.ts +152 -0
  511. package/testing-base/src/lib/components/mock.popover.component.ts +22 -0
  512. package/testing-base/src/lib/components/mock.progress-circle.component.ts +22 -0
  513. package/testing-base/src/lib/components/mock.radio-group.component.ts +27 -0
  514. package/testing-base/src/lib/components/mock.radio.component.ts +23 -0
  515. package/testing-base/src/lib/components/mock.range.component.ts +35 -0
  516. package/testing-base/src/lib/components/mock.reorder-list.component.ts +25 -0
  517. package/testing-base/src/lib/components/mock.router-outlet.component.ts +20 -0
  518. package/testing-base/src/lib/components/mock.section-header.component.ts +18 -0
  519. package/testing-base/src/lib/components/mock.segmented-control.component.ts +29 -0
  520. package/testing-base/src/lib/components/mock.slide-button.component.ts +23 -0
  521. package/testing-base/src/lib/components/mock.slides.component.ts +29 -0
  522. package/testing-base/src/lib/components/mock.spinner.component.ts +18 -0
  523. package/testing-base/src/lib/components/mock.tab-button.component.ts +21 -0
  524. package/testing-base/src/lib/components/mock.tabs.component.ts +18 -0
  525. package/testing-base/src/lib/components/mock.textarea.component.ts +26 -0
  526. package/testing-base/src/lib/components/mock.toggle-button.component.ts +21 -0
  527. package/testing-base/src/lib/components/mock.toggle.component.ts +22 -0
  528. package/testing-base/src/lib/components/mock.web-component-proxies.component.ts +32 -0
  529. package/testing-base/src/lib/directives/index.ts +3 -0
  530. package/testing-base/src/lib/directives/mock.accordion.directive.ts +15 -0
  531. package/testing-base/src/lib/directives/mock.fit-heading.directive.ts +19 -0
  532. package/testing-base/src/lib/directives/mock.theme-color.directive.ts +19 -0
  533. package/testing-base/src/lib/index.ts +4 -0
  534. package/testing-base/src/lib/kirby-testing-base.module.ts +10 -0
  535. package/testing-base/src/lib/mock-components.ts +133 -0
  536. package/testing-base/src/lib/mock-directives.ts +9 -0
  537. package/testing-base/src/public_api.ts +1 -0
  538. package/testing-base/src/tsconfig.json +9 -0
  539. package/testing-jasmine/ng-package.json +3 -0
  540. package/testing-jasmine/src/lib/kirby-testing.module.ts +14 -0
  541. package/testing-jasmine/src/lib/mock-providers.ts +68 -0
  542. package/testing-jasmine/src/public_api.ts +1 -0
  543. package/testing-jasmine/src/tsconfig.json +10 -0
  544. package/testing-jest/ng-package.json +3 -0
  545. package/testing-jest/src/lib/kirby-testing.module.ts +14 -0
  546. package/testing-jest/src/lib/mock-providers.ts +76 -0
  547. package/testing-jest/src/public_api.ts +1 -0
  548. package/testing-jest/src/tsconfig.json +10 -0
  549. package/tsconfig.json +17 -0
  550. package/tsconfig.lib.json +23 -0
  551. package/tsconfig.spec.json +9 -0
  552. package/tslint.json +10 -0
@@ -0,0 +1,1004 @@
1
+ import { ElementRef } from '@angular/core';
2
+ import { createServiceFactory, SpectatorService } from '@ngneat/spectator';
3
+ import { Chart, ChartDataset as ChartJSDataset, ChartType as ChartJSType } from 'chart.js';
4
+ import { AnnotationOptions } from 'chartjs-plugin-annotation';
5
+ import { MockProvider } from 'ng-mocks';
6
+
7
+ import { deepCopy } from '../../../helpers/deep-copy';
8
+ import { ChartDataset, ChartType } from '../chart.types';
9
+ import { ChartHighlightedElements } from '../chart.types';
10
+ import { ChartConfigService } from '../configs/chart-config.service';
11
+ import { CHART_GLOBAL_DEFAULTS } from '../configs/global-defaults.config';
12
+
13
+ import { ChartJSService } from './chart-js.service';
14
+ import { TEST_CHART_ANNOTATIONS_CONFIG, TEST_CHART_TYPES_CONFIG } from './test-utils';
15
+
16
+ describe('ChartJSService', () => {
17
+ let spectator: SpectatorService<ChartJSService>;
18
+ let chartJSService: ChartJSService;
19
+ let canvasElement: ElementRef<HTMLCanvasElement>;
20
+
21
+ const mockChartConfigService = MockProvider(ChartConfigService, {
22
+ getTypeConfig: (chartType: ChartType) => deepCopy(TEST_CHART_TYPES_CONFIG[chartType]),
23
+ getInteractionFunctionsExtensions: () => ({ onHover: () => null }),
24
+ getAnnotationDefaults: (type: string) => TEST_CHART_ANNOTATIONS_CONFIG[type],
25
+ chartTypeToChartJSType: (type: ChartType) => TEST_CHART_TYPES_CONFIG[type].type as ChartJSType,
26
+ });
27
+
28
+ const createService = createServiceFactory({
29
+ service: ChartJSService,
30
+ providers: [mockChartConfigService],
31
+ });
32
+
33
+ beforeEach(() => {
34
+ spectator = createService();
35
+ const nativeElement = document.createElement('canvas');
36
+
37
+ chartJSService = spectator.service;
38
+ canvasElement = new ElementRef<HTMLCanvasElement>(nativeElement);
39
+ });
40
+
41
+ describe('function: renderChart', () => {
42
+ it('should render chart with correct defaults for filler plugin', () => {
43
+ const data = [7, 7.37, 7.46];
44
+
45
+ chartJSService.renderChart({
46
+ targetElement: canvasElement,
47
+ type: 'line',
48
+ data: data,
49
+ labels: ['one', 'two', 'three'],
50
+ });
51
+
52
+ const fillerOptions = chartJSService['chart'].options.plugins.filler;
53
+
54
+ expect(fillerOptions.propagate).toBeTrue();
55
+ expect(fillerOptions.drawTime).toBe('beforeDatasetDraw');
56
+ });
57
+
58
+ describe('when annotations are given', () => {
59
+ it('should render the chart with annotations applied', () => {
60
+ const annotations: AnnotationOptions[] = [
61
+ { type: 'line', yMin: 10, yMax: 10 },
62
+ { type: 'line', yMin: 20, yMax: 20 },
63
+ ];
64
+
65
+ chartJSService.renderChart({
66
+ targetElement: canvasElement,
67
+ type: 'bar',
68
+ data: [1, 2, 3],
69
+ labels: ['one', 'two', 'three'],
70
+ annotations,
71
+ });
72
+
73
+ expect(chartJSService['chart'].options.plugins.annotation.annotations.length).toEqual(2);
74
+ });
75
+ });
76
+
77
+ describe('when data is given as a number[]', () => {
78
+ it('should render a new chart', () => {
79
+ expect(chartJSService['chart']).toBeUndefined();
80
+
81
+ chartJSService.renderChart({
82
+ targetElement: canvasElement,
83
+ type: 'bar',
84
+ data: [1, 2, 3],
85
+ labels: ['one', 'two', 'three'],
86
+ });
87
+
88
+ expect(chartJSService['chart']).toBeInstanceOf(Chart);
89
+ });
90
+
91
+ it('should use the supplied data in the chart', () => {
92
+ const data = [1, 2, 3];
93
+
94
+ chartJSService.renderChart({
95
+ targetElement: canvasElement,
96
+ type: 'bar',
97
+ data,
98
+ labels: ['one', 'two', 'three'],
99
+ });
100
+
101
+ const chart = chartJSService['chart'];
102
+ expect(chart.data.datasets[0].data).toEqual(data);
103
+ });
104
+
105
+ describe('when highlightedElements are given', () => {
106
+ it('should mark given elements as highlighted', () => {
107
+ const highlightedElements = [
108
+ [0, 0],
109
+ [0, 2],
110
+ ];
111
+
112
+ chartJSService.renderChart({
113
+ targetElement: canvasElement,
114
+ type: 'bar',
115
+ data: [1, 2, 3],
116
+ labels: ['one', 'two', 'three'],
117
+ highlightedElements,
118
+ });
119
+
120
+ const datasets = chartJSService['chart'].data.datasets as ChartDataset[];
121
+
122
+ expect(datasets.length).toEqual(1);
123
+ expect(datasets[0].kirbyOptions.highlightedElements).toEqual([0, 2]);
124
+ });
125
+ });
126
+ });
127
+
128
+ describe('when custom options are given', () => {
129
+ it('should overwrite options set by global defaults', () => {
130
+ // Check if a global default is actually being overwritten
131
+ expect(CHART_GLOBAL_DEFAULTS.elements.bar.backgroundColor).not.toBeUndefined();
132
+ const customElementBackgroundColor = '#ffffff';
133
+
134
+ chartJSService.renderChart({
135
+ targetElement: canvasElement,
136
+ type: 'bar',
137
+ data: [1, 2, 3],
138
+ labels: ['one', 'two', 'three'],
139
+ customOptions: {
140
+ elements: {
141
+ bar: {
142
+ backgroundColor: customElementBackgroundColor,
143
+ },
144
+ },
145
+ },
146
+ });
147
+
148
+ const chart = chartJSService['chart'];
149
+ expect(chart.options.elements.bar.backgroundColor).toEqual(customElementBackgroundColor);
150
+ });
151
+
152
+ it('should overwrite type specific options', () => {
153
+ // Check if a type config is actually being overwritten
154
+ const type = 'bar';
155
+ const customIndexAxis = 'x';
156
+ expect(TEST_CHART_TYPES_CONFIG[type].options.indexAxis).toBe('y');
157
+
158
+ chartJSService.renderChart({
159
+ targetElement: canvasElement,
160
+ type: type,
161
+ data: [1, 2, 3],
162
+ labels: ['one', 'two', 'three'],
163
+ customOptions: {
164
+ indexAxis: customIndexAxis,
165
+ },
166
+ });
167
+
168
+ const chart = chartJSService['chart'];
169
+ expect(chart.options.indexAxis).toEqual(customIndexAxis);
170
+ });
171
+ });
172
+
173
+ describe('when labels are provided', () => {
174
+ describe("via 'labels' argument", () => {
175
+ it('should apply them to the graph', () => {
176
+ const data = [1, 2, 3];
177
+ const labels = ['one', 'two', 'three'];
178
+ expect(labels.length).toBeGreaterThan(0);
179
+ expect(data.length).toBeGreaterThan(0);
180
+
181
+ chartJSService.renderChart({
182
+ targetElement: canvasElement,
183
+ type: 'bar',
184
+ data,
185
+ labels,
186
+ });
187
+
188
+ const chartLabels = chartJSService['chart'].data.labels;
189
+ expect(chartLabels.length).toEqual(labels.length);
190
+ expect(chartLabels).toEqual(labels);
191
+ });
192
+
193
+ describe('and the dataset also contains labels', () => {
194
+ it('should apply argument labels', () => {
195
+ const data = [
196
+ {
197
+ data: [
198
+ { x: 'en', y: 1 },
199
+ { x: 'to', y: 2 },
200
+ { x: 'tre', y: 3 },
201
+ ],
202
+ },
203
+ ] as any;
204
+ const labels = ['one', 'two', 'three'];
205
+ expect(labels.length).toBeGreaterThan(0);
206
+ expect(data.length).toBeGreaterThan(0);
207
+
208
+ chartJSService.renderChart({
209
+ targetElement: canvasElement,
210
+ type: 'column',
211
+ data,
212
+ labels,
213
+ });
214
+
215
+ const chartLabels = chartJSService['chart'].data.labels;
216
+ expect(chartLabels.length).toEqual(labels.length);
217
+ expect(chartLabels).toEqual(labels);
218
+ });
219
+ });
220
+ });
221
+ });
222
+
223
+ describe('when no labels are provided', () => {
224
+ it('should have a blank label for each data point', () => {
225
+ const data = [1, 2, 3];
226
+ const expectedLabels = ['', '', ''];
227
+ expect(data.length).toBeGreaterThan(0);
228
+ expect(expectedLabels.length).toEqual(data.length);
229
+
230
+ chartJSService.renderChart({
231
+ targetElement: canvasElement,
232
+ type: 'column',
233
+ data,
234
+ });
235
+
236
+ const chartLabels = chartJSService['chart'].data.labels;
237
+ expect(chartLabels.length).toEqual(data.length);
238
+ expect(chartLabels).toEqual(expectedLabels);
239
+ });
240
+
241
+ describe('but the dataset contains labels for the index axis', () => {
242
+ it('should use the dataset labels', () => {
243
+ const data = [
244
+ { x: 'en', y: 1 },
245
+ { x: 'to', y: 2 },
246
+ { x: 'tre', y: 3 },
247
+ ] as any;
248
+ const dataset = [
249
+ {
250
+ data,
251
+ },
252
+ ];
253
+ expect(data.length).toBeGreaterThan(0);
254
+ expect(data.every(({ x }) => typeof x === 'string')).toBeTrue();
255
+
256
+ chartJSService.renderChart({
257
+ targetElement: canvasElement,
258
+ type: 'column',
259
+ data: dataset,
260
+ });
261
+
262
+ /* This assertion relies on the assumption that:
263
+ 1. if chart.data.labels is empty &
264
+ 2. datasets contains string along the index axis
265
+ : then the strings in datasets will be used as labels.
266
+
267
+ This assumption comes from the internal logic of chartjs.
268
+ */
269
+ const chartData = chartJSService['chart'].data;
270
+ expect(chartJSService['chart'].options.indexAxis).toEqual('x');
271
+ expect(chartData.labels.length).toEqual(0);
272
+ expect(chartData.datasets).toEqual(dataset);
273
+ });
274
+ });
275
+
276
+ describe('function: createConfigurationObject', () => {
277
+ it('should not be filled with blank labels if type is stock', () => {
278
+ const stockChartConfig = {
279
+ targetElement: canvasElement,
280
+ type: 'stock' as ChartType,
281
+ data: [
282
+ {
283
+ data: [
284
+ { x: 10, y: 5 },
285
+ { x: 11, y: 6 },
286
+ { x: 13, y: 6 },
287
+ ],
288
+ },
289
+ ],
290
+ };
291
+ chartJSService.renderChart(stockChartConfig);
292
+
293
+ expect(chartJSService['chart'].data.labels.length).toEqual(3);
294
+ chartJSService['chart'].data.labels.forEach((label) => {
295
+ expect(label).not.toBe('');
296
+ });
297
+ });
298
+ });
299
+
300
+ describe('when data is given as a chartJSDataset[]', () => {
301
+ it('should render a new chart', () => {
302
+ expect(chartJSService['chart']).toBeUndefined();
303
+
304
+ chartJSService.renderChart({
305
+ targetElement: canvasElement,
306
+ type: 'bar',
307
+ data: [{ data: [1, 2, 3] }],
308
+ labels: ['one', 'two', 'three'],
309
+ });
310
+
311
+ expect(chartJSService['chart']).toBeInstanceOf(Chart);
312
+ });
313
+
314
+ it('should use the supplied data in the chart', () => {
315
+ const data = [1, 2, 3];
316
+ const dataset = {
317
+ data: data,
318
+ };
319
+
320
+ chartJSService.renderChart({
321
+ targetElement: canvasElement,
322
+ type: 'bar',
323
+ data: [dataset],
324
+ labels: ['one', 'two', 'three'],
325
+ });
326
+
327
+ const chart = chartJSService['chart'];
328
+ expect(chart.data.datasets[0].data).toEqual(data);
329
+ });
330
+
331
+ describe('that contains more than one entry', () => {
332
+ it('should use every supplied dataset in the chart', () => {
333
+ const data1 = [1, 2, 3];
334
+ const data2 = [4, 5, 6];
335
+ const datasets = [
336
+ {
337
+ data: data1,
338
+ },
339
+ { data: data2 },
340
+ ];
341
+
342
+ chartJSService.renderChart({
343
+ targetElement: canvasElement,
344
+ type: 'bar',
345
+ data: datasets,
346
+ labels: ['one', 'two', 'three'],
347
+ });
348
+
349
+ const chart = chartJSService['chart'];
350
+ expect(chart.data.datasets[0].data).toEqual(data1);
351
+ expect(chart.data.datasets[1].data).toEqual(data2);
352
+ });
353
+ });
354
+
355
+ describe('when highlightedElements are given', () => {
356
+ it('should mark given elements as highlighted', () => {
357
+ const highlightedElements = [
358
+ [0, 0],
359
+ [0, 2],
360
+ ];
361
+
362
+ chartJSService.renderChart({
363
+ targetElement: canvasElement,
364
+ type: 'bar',
365
+ data: [{ data: [1, 2, 3] }],
366
+ labels: ['one', 'two', 'three'],
367
+ highlightedElements,
368
+ });
369
+
370
+ const datasets = chartJSService['chart'].data.datasets as ChartDataset[];
371
+
372
+ expect(datasets.length).toEqual(1);
373
+ expect(datasets[0].kirbyOptions.highlightedElements).toEqual([0, 2]);
374
+ });
375
+ });
376
+ });
377
+ });
378
+ });
379
+
380
+ describe('function: redrawChart', () => {
381
+ beforeEach(() => {
382
+ chartJSService.renderChart({
383
+ targetElement: canvasElement,
384
+ type: 'bar',
385
+ data: [1, 2, 3],
386
+ labels: ['one', 'two', 'three'],
387
+ });
388
+ });
389
+
390
+ it('should update the chart', () => {
391
+ const updateSpy = spyOn(chartJSService['chart'], 'update');
392
+
393
+ chartJSService.redrawChart();
394
+
395
+ expect(updateSpy).toHaveBeenCalledTimes(1);
396
+ });
397
+
398
+ it('should keep the same chart', () => {
399
+ const initialId = chartJSService['chart'].id;
400
+
401
+ chartJSService.redrawChart();
402
+
403
+ expect(chartJSService['chart'].id).toEqual(initialId);
404
+ });
405
+ });
406
+
407
+ describe('function: updateData', () => {
408
+ let chart: Chart;
409
+
410
+ beforeEach(() => {
411
+ chartJSService.renderChart({
412
+ targetElement: canvasElement,
413
+ type: 'bar',
414
+ data: [1, 2, 3],
415
+ labels: ['one', 'two', 'three'],
416
+ });
417
+ chart = chartJSService['chart'];
418
+ });
419
+
420
+ describe('when data is given as a number[]', () => {
421
+ it('should update the chart data', () => {
422
+ const newData = [4, 5, 6];
423
+ expect(chart.data.datasets[0].data).not.toEqual(newData);
424
+
425
+ chartJSService.updateData(newData);
426
+
427
+ expect(chart.data.datasets[0].data).toEqual(newData);
428
+ });
429
+ });
430
+
431
+ describe('when data is given as a chartJSDataset[]', () => {
432
+ it('should update the chart data', () => {
433
+ const newDataset = [
434
+ {
435
+ data: [7, 8, 9],
436
+ },
437
+ ];
438
+ expect(chart.data.datasets[0].data).not.toEqual(newDataset[0].data);
439
+
440
+ chartJSService.updateData(newDataset);
441
+
442
+ expect(chart.data.datasets[0].data).toEqual(newDataset[0].data);
443
+ });
444
+
445
+ describe('that contains more than one entry', () => {
446
+ it('should update to have multiple datasets', () => {
447
+ const newDatasets = [
448
+ {
449
+ data: [7, 8, 9],
450
+ },
451
+ { data: [10, 11, 12] },
452
+ ];
453
+ expect(chart.data.datasets.length).toBe(1);
454
+
455
+ chartJSService.updateData(newDatasets);
456
+
457
+ expect(chart.data.datasets[0].data).toEqual(newDatasets[0].data);
458
+ expect(chart.data.datasets[1].data).toEqual(newDatasets[1].data);
459
+ });
460
+ });
461
+ });
462
+ });
463
+
464
+ describe('function: updateLabels', () => {
465
+ let chart: Chart;
466
+
467
+ beforeEach(() => {
468
+ chartJSService.renderChart({
469
+ targetElement: canvasElement,
470
+ type: 'bar',
471
+ data: [1, 2, 3],
472
+ labels: ['one', 'two', 'three'],
473
+ });
474
+ chart = chartJSService['chart'];
475
+ });
476
+
477
+ it('should update the labels of the chart', () => {
478
+ const newLabels = ['four', 'five', 'six'];
479
+ expect(chart.data.labels).not.toEqual(newLabels);
480
+
481
+ chartJSService.updateLabels(newLabels);
482
+
483
+ expect(chart.data.labels).toEqual(newLabels);
484
+ });
485
+ });
486
+
487
+ describe('function: updateType', () => {
488
+ beforeEach(() => {
489
+ chartJSService.renderChart({
490
+ targetElement: canvasElement,
491
+ type: 'bar',
492
+ data: [1, 2, 3],
493
+ labels: ['one', 'two', 'three'],
494
+ });
495
+ });
496
+
497
+ let chartTypesThatDestructivelyUpdate: ChartType[] = ['bar', 'column'];
498
+ let chartTypesThatUpdateNormally: ChartType[] = ['line'];
499
+
500
+ chartTypesThatDestructivelyUpdate.forEach((chartType) => {
501
+ describe(`if the new type is ChartType.${chartType}`, () => {
502
+ it('should destructively update type', () => {
503
+ const destructivelyUpdateTypeSpy = spyOn<any>(chartJSService, 'destructivelyUpdateType');
504
+
505
+ chartJSService.updateType(chartType, {});
506
+
507
+ expect(destructivelyUpdateTypeSpy).toHaveBeenCalledTimes(1);
508
+ });
509
+ });
510
+ });
511
+
512
+ chartTypesThatUpdateNormally.forEach((chartType) => {
513
+ describe(`if the new type is ChartType.${chartType}`, () => {
514
+ it('should non-destructively update type', () => {
515
+ const nonDestructivelyUpdateTypeSpy = spyOn<any>(
516
+ chartJSService,
517
+ 'nonDestructivelyUpdateType'
518
+ );
519
+
520
+ chartJSService.updateType(chartType, {});
521
+
522
+ expect(nonDestructivelyUpdateTypeSpy).toHaveBeenCalledTimes(1);
523
+ });
524
+ });
525
+ });
526
+ });
527
+
528
+ describe('private function: createOptionsObject', () => {
529
+ it('should apply interaction functions extensions', () => {
530
+ const applyInteractionFunctionsExtensionsSpy = spyOn<any>(
531
+ chartJSService,
532
+ 'applyInteractionFunctionsExtensions'
533
+ );
534
+
535
+ chartJSService['createOptionsObject']({});
536
+
537
+ expect(applyInteractionFunctionsExtensionsSpy).toHaveBeenCalledTimes(1);
538
+ });
539
+ });
540
+
541
+ describe('private function: nonDestructivelyUpdateType', () => {
542
+ let chart: Chart;
543
+
544
+ beforeEach(() => {
545
+ chartJSService.renderChart({
546
+ targetElement: canvasElement,
547
+ type: 'bar',
548
+ data: [1, 2, 3],
549
+ labels: ['one', 'two', 'three'],
550
+ annotations: [{ type: 'line', yMin: 10, yMax: 10 }],
551
+ });
552
+ chart = chartJSService['chart'];
553
+ });
554
+
555
+ it('should set a new type', () => {
556
+ const oldType = chart.config.type;
557
+ const newType = 'line';
558
+ expect(oldType).not.toBe(newType);
559
+
560
+ chartJSService['nonDestructivelyUpdateType']('line');
561
+
562
+ expect(chart.config.type).not.toBe(oldType);
563
+ expect(newType).toBe('line');
564
+ });
565
+
566
+ it('should apply config from new type', () => {
567
+ const newType = 'line';
568
+ const newBorderColor = TEST_CHART_TYPES_CONFIG[newType].options.elements.line.borderColor;
569
+ expect(chart.options.elements.line.borderColor).not.toEqual(newBorderColor);
570
+
571
+ chartJSService['nonDestructivelyUpdateType'](newType);
572
+ chart.update(); // An update is needed for changes to be reflected
573
+
574
+ expect(chart.options.elements.line.borderColor).toEqual(newBorderColor);
575
+ });
576
+
577
+ it('should apply custom options', () => {
578
+ const oldBackgroundColor = chart.options.bar?.datasets?.backgroundColor;
579
+ const newBackgroundColor = 'rgba(125,124,123,1)';
580
+
581
+ chartJSService['nonDestructivelyUpdateType']('line', {
582
+ elements: { bar: { backgroundColor: newBackgroundColor } },
583
+ });
584
+
585
+ expect(oldBackgroundColor).toBeUndefined();
586
+ expect(chart.config.options.elements.bar.backgroundColor).toBe(newBackgroundColor);
587
+ });
588
+
589
+ it('should preserve the chart', () => {
590
+ const oldChartId = chart.id;
591
+
592
+ chartJSService['nonDestructivelyUpdateType']('bar');
593
+
594
+ expect(chartJSService['chart'].id).toEqual(oldChartId);
595
+ });
596
+
597
+ it('should preserve the original labels', () => {
598
+ const oldDatalabels = chart.data.labels;
599
+
600
+ chartJSService['nonDestructivelyUpdateType']('line');
601
+
602
+ expect(chartJSService['chart'].data.labels).toEqual(oldDatalabels);
603
+ });
604
+
605
+ it('should preserve the original annotations', () => {
606
+ const oldAnnotations = chart.options.plugins.annotation.annotations;
607
+
608
+ chartJSService['nonDestructivelyUpdateType']('line');
609
+ chart.update(); // Annotation changes are not visible before update
610
+
611
+ const newAnnotations = chartJSService['chart'].options.plugins.annotation.annotations;
612
+
613
+ expect(newAnnotations).toEqual(oldAnnotations);
614
+ });
615
+ });
616
+
617
+ describe('private function: destructivelyUpdateType', () => {
618
+ let chart: Chart;
619
+
620
+ beforeEach(() => {
621
+ chartJSService.renderChart({
622
+ targetElement: canvasElement,
623
+ type: 'bar',
624
+ data: [1, 2, 3],
625
+ labels: ['one', 'two', 'three'],
626
+ annotations: [{ type: 'line', yMin: 10, yMax: 10 }],
627
+ });
628
+ chart = chartJSService['chart'];
629
+ });
630
+
631
+ it('should replace the old chart element', () => {
632
+ const oldChartId = chart.id;
633
+
634
+ chartJSService['destructivelyUpdateType']('bar');
635
+
636
+ expect(chartJSService['chart'].id).not.toEqual(oldChartId);
637
+ });
638
+
639
+ it('should preserve the original data', () => {
640
+ const oldDatasets = chart.data.datasets;
641
+
642
+ chartJSService['destructivelyUpdateType']('bar');
643
+
644
+ expect(chartJSService['chart'].data.datasets).toEqual(oldDatasets);
645
+ });
646
+
647
+ it('should preserve the original labels', () => {
648
+ const oldDatalabels = chart.data.labels;
649
+
650
+ chartJSService['destructivelyUpdateType']('bar');
651
+
652
+ expect(chartJSService['chart'].data.labels).toEqual(oldDatalabels);
653
+ });
654
+
655
+ it('should preserve the original annotations', () => {
656
+ const oldAnnotations = chart.options.plugins.annotation.annotations;
657
+
658
+ chartJSService['destructivelyUpdateType']('bar');
659
+
660
+ expect(chartJSService['chart'].options.plugins.annotation.annotations).toEqual(
661
+ oldAnnotations
662
+ );
663
+ });
664
+ });
665
+
666
+ describe('function: updateOptions', () => {
667
+ const chartType = 'bar';
668
+ let annotations: AnnotationOptions[];
669
+
670
+ beforeEach(() => {
671
+ annotations = [{ type: 'line', yMin: 20, yMax: 20 }];
672
+ chartJSService.renderChart({
673
+ targetElement: canvasElement,
674
+ type: chartType,
675
+ data: [1, 2, 3],
676
+ labels: ['one', 'two', 'three'],
677
+ customOptions: {
678
+ borderColor: 'pink',
679
+ },
680
+ annotations,
681
+ });
682
+ });
683
+
684
+ it('should overwrite existing custom options', () => {
685
+ expect(chartJSService['chart'].options.borderColor).toEqual('pink');
686
+
687
+ chartJSService.updateOptions(
688
+ {
689
+ borderColor: 'red',
690
+ },
691
+ chartType
692
+ );
693
+ // Options are resolved as part of update
694
+ chartJSService['chart'].update();
695
+
696
+ expect(chartJSService['chart'].options.borderColor).toEqual('red');
697
+ });
698
+
699
+ it('should overwrite options set by global defaults', () => {
700
+ // Check if a global default is actually being overwritten
701
+ expect(CHART_GLOBAL_DEFAULTS.elements.bar.backgroundColor).not.toBeUndefined();
702
+ const customElementBackgroundColor = '#ffffff';
703
+
704
+ chartJSService.updateOptions(
705
+ {
706
+ elements: {
707
+ bar: {
708
+ backgroundColor: customElementBackgroundColor,
709
+ },
710
+ },
711
+ },
712
+ chartType
713
+ );
714
+ // Options are resolved as part of update
715
+ chartJSService['chart'].update();
716
+
717
+ expect(chartJSService['chart'].options.elements.bar.backgroundColor).toEqual(
718
+ customElementBackgroundColor
719
+ );
720
+ });
721
+
722
+ it('should overwrite type specific options', () => {
723
+ // Check if a type config is actually being overwritten
724
+ const customIndexAxis = 'x';
725
+ expect(TEST_CHART_TYPES_CONFIG[chartType].options.indexAxis).not.toBeUndefined();
726
+ expect(TEST_CHART_TYPES_CONFIG[chartType].options.indexAxis).not.toEqual(customIndexAxis);
727
+
728
+ chartJSService.updateOptions(
729
+ {
730
+ indexAxis: customIndexAxis,
731
+ },
732
+ chartType
733
+ );
734
+ // Options are resolved as part of update
735
+ chartJSService['chart'].update();
736
+
737
+ const chart = chartJSService['chart'];
738
+ expect(chart.options.indexAxis).toEqual(customIndexAxis);
739
+ });
740
+
741
+ it('should preserve the original annotations', () => {
742
+ const oldAnnotations = chartJSService['chart'].options.plugins.annotation.annotations;
743
+
744
+ chartJSService.updateOptions(
745
+ {
746
+ indexAxis: 'x',
747
+ },
748
+ chartType
749
+ );
750
+ chartJSService['chart'].update();
751
+
752
+ const newAnnotations = chartJSService['chart'].options.plugins.annotation.annotations;
753
+ expect(newAnnotations.length).not.toBe(0);
754
+ expect(newAnnotations).toEqual(oldAnnotations);
755
+ });
756
+ });
757
+
758
+ describe('function: updateHighlightedElements', () => {
759
+ let data: ChartDataset[] | number[];
760
+ let chart: Chart;
761
+
762
+ beforeEach(() => {
763
+ data = [{ data: [1, 2, 3] }, { data: [4, 5, 6] }, { data: [7, 8, 9] }];
764
+ chartJSService.renderChart({
765
+ targetElement: canvasElement,
766
+ type: 'bar',
767
+ data,
768
+ labels: ['one', 'two', 'three'],
769
+ });
770
+ chart = chartJSService['chart'];
771
+ });
772
+
773
+ it('should mark the given elements as highlighted for respective datasets', () => {
774
+ /* I have not found a way to directly test which color each datapoint is rendered with.
775
+ That would however have been the better approach, as it can be seen directly how it is
776
+ rendered. But this will suffice for now - the assumption is, that if it is marked
777
+ as highlighted in the dataset, it is rendered with the correct color */
778
+ const highlightedElements: ChartHighlightedElements = [
779
+ [0, 1],
780
+ [0, 2],
781
+ [2, 1],
782
+ [2, 2],
783
+ ];
784
+
785
+ chartJSService.updateHighlightedElements(highlightedElements);
786
+ chart.update();
787
+
788
+ highlightedElements.forEach(([datasetIndex, dataIndex]) => {
789
+ const dataset = chart.data.datasets[datasetIndex] as ChartDataset;
790
+ expect(dataset.kirbyOptions.highlightedElements.includes(dataIndex)).toBeTrue();
791
+ });
792
+ });
793
+
794
+ it('should preserve the original data', () => {
795
+ const originalData = chart.data.datasets.map((dataset) => dataset.data);
796
+
797
+ chartJSService.updateHighlightedElements([
798
+ [0, 1],
799
+ [0, 2],
800
+ [2, 1],
801
+ [2, 2],
802
+ ]);
803
+ chart.update();
804
+
805
+ const newData = chart.data.datasets.map((dataset) => dataset.data);
806
+ expect(originalData).toEqual(newData);
807
+ });
808
+
809
+ describe('when there already are highlighted elements', () => {
810
+ let highlightedElements: ChartHighlightedElements;
811
+
812
+ beforeEach(() => {
813
+ highlightedElements = [
814
+ [0, 1],
815
+ [0, 2],
816
+ ];
817
+ chartJSService.updateHighlightedElements(highlightedElements);
818
+ chart.update();
819
+ });
820
+
821
+ it('should clear the highlight from existing elements', () => {
822
+ chartJSService.updateHighlightedElements([
823
+ [1, 1],
824
+ [1, 2],
825
+ ]);
826
+ chart.update();
827
+
828
+ highlightedElements.forEach(([datasetIndex, dataIndex]) => {
829
+ const dataset = chart.data.datasets[datasetIndex] as ChartDataset;
830
+ expect(dataset?.kirbyOptions?.highlightedElements?.includes(dataIndex)).toBeFalsy();
831
+ });
832
+ });
833
+
834
+ it('should be possible to remove all highlights by passing an empty array', () => {
835
+ chartJSService.updateHighlightedElements([]);
836
+ chart.update();
837
+
838
+ const datasets = chart.data.datasets as ChartDataset[];
839
+ datasets.forEach((dataset) => {
840
+ expect(dataset?.kirbyOptions?.highlightedElements).toBeFalsy();
841
+ });
842
+ });
843
+
844
+ it('should be possible to remove all highlights by passing nothing', () => {
845
+ chartJSService.updateHighlightedElements();
846
+ chart.update();
847
+
848
+ const datasets = chart.data.datasets as ChartDataset[];
849
+ datasets.forEach((dataset) => {
850
+ expect(dataset?.kirbyOptions?.highlightedElements).toBeFalsy();
851
+ });
852
+ });
853
+ });
854
+ });
855
+
856
+ describe('function: updateAnnotations', () => {
857
+ const chartType = 'bar';
858
+ let chart: Chart;
859
+
860
+ beforeEach(() => {
861
+ chartJSService.renderChart({
862
+ targetElement: canvasElement,
863
+ type: chartType,
864
+ data: [1, 2, 3],
865
+ labels: ['one', 'two', 'three'],
866
+ });
867
+ chart = chartJSService['chart'];
868
+ });
869
+
870
+ describe('if the chart already has annotations applied', () => {
871
+ beforeEach(() => {
872
+ chart.options.plugins.annotation.annotations = [
873
+ { type: 'line', yMin: -10, yMax: -10 },
874
+ { type: 'line', yMin: 0, yMax: 0 },
875
+ ];
876
+ chartJSService.redrawChart();
877
+ expect(chart.options.plugins.annotation.annotations.length).toEqual(2);
878
+ });
879
+
880
+ it('should replace the annotations with new ones', () => {
881
+ const newAnnotations: AnnotationOptions[] = [
882
+ { type: 'line', yMin: 10, yMax: 10 },
883
+ { type: 'line', yMin: 20, yMax: 20 },
884
+ ];
885
+
886
+ chartJSService.updateAnnotations(newAnnotations);
887
+ chartJSService.redrawChart();
888
+
889
+ const chartAnnotations = chartJSService['chart'].options.plugins.annotation.annotations;
890
+ newAnnotations.forEach((newAnnotation, index) => {
891
+ const chartAnnotation = chartAnnotations[index];
892
+ expect(newAnnotation['yMin']).toEqual(chartAnnotation['yMin']);
893
+ expect(newAnnotation['yMax']).toEqual(chartAnnotation['yMax']);
894
+ });
895
+ expect(chartAnnotations.length).toBe(2);
896
+ });
897
+
898
+ it('should be possible to remove the annotations by passing an empty array', () => {
899
+ chartJSService.updateAnnotations([]);
900
+ chartJSService.redrawChart();
901
+ expect(chart.options.plugins.annotation.annotations.length).toEqual(0);
902
+ });
903
+ });
904
+
905
+ describe('if the chart has no annotations applied', () => {
906
+ beforeEach(() => {
907
+ expect(chart.options.plugins.annotation.annotations).toEqual({});
908
+ });
909
+
910
+ it('should add annotations to the chart', () => {
911
+ const annotations: AnnotationOptions[] = [
912
+ { type: 'line', yMin: 10, yMax: 10 },
913
+ { type: 'line', yMin: 20, yMax: 20 },
914
+ ];
915
+ expect(chart.options.plugins.annotation.annotations).toEqual(Object.create(null));
916
+
917
+ chartJSService.updateAnnotations(annotations);
918
+ chartJSService.redrawChart();
919
+
920
+ expect(chart.options.plugins.annotation.annotations.length).toEqual(2);
921
+ });
922
+ });
923
+
924
+ it('should preserve annotation defaults if they are not overwritten', () => {
925
+ const annotations: AnnotationOptions[] = [
926
+ { type: 'line', yMin: 10, yMax: 10 },
927
+ { type: 'line', yMin: 20, yMax: 20 },
928
+ ];
929
+
930
+ chartJSService.updateAnnotations(annotations);
931
+ chartJSService.redrawChart();
932
+
933
+ const chartAnnotations = chart.options.plugins.annotation.annotations as AnnotationOptions[];
934
+
935
+ chartAnnotations.forEach((chartAnnotation) => {
936
+ const annotationDefaults = TEST_CHART_ANNOTATIONS_CONFIG[chartAnnotation.type];
937
+ Object.entries(annotationDefaults).forEach(([key, _]) => {
938
+ expect(chartAnnotation[key]).toEqual(annotationDefaults[key]);
939
+ });
940
+ });
941
+ });
942
+
943
+ it('should be possible to overwrite annotation defaults', () => {
944
+ expect(TEST_CHART_ANNOTATIONS_CONFIG['line']['borderDash']).toEqual([6, 3]);
945
+ const annotations: AnnotationOptions[] = [
946
+ { type: 'line', yMin: 10, yMax: 10, borderDash: [10, 10] },
947
+ { type: 'line', yMin: 20, yMax: 20, borderDash: [10, 10] },
948
+ ];
949
+
950
+ chartJSService.updateAnnotations(annotations);
951
+ chartJSService.redrawChart();
952
+
953
+ const chartAnnotations = chart.options.plugins.annotation.annotations as AnnotationOptions[];
954
+ chartAnnotations.forEach((chartAnnotation) => {
955
+ expect(chartAnnotation.borderDash).toEqual([10, 10]);
956
+ });
957
+ });
958
+ });
959
+
960
+ describe('function: addDataLabelsData', () => {
961
+ const data: ChartDataset[] = [
962
+ {
963
+ data: [
964
+ { x: 10, y: 3 },
965
+ { x: 2, y: 7 },
966
+ { x: 19, y: -10 },
967
+ ],
968
+ },
969
+ ];
970
+ const flatDataset: number[] = [1, 2, 3, 4, 5];
971
+
972
+ describe('when dataset is a flat array', () => {
973
+ it('should throw an error if dataset is a flat array', () => {
974
+ chartJSService.setDataLabelOptions({});
975
+ expect(function () {
976
+ chartJSService.addDataLabelsData(flatDataset);
977
+ }).toThrowError();
978
+ });
979
+ });
980
+
981
+ const dataLabelOptionsProperties = ['showMax', 'showMin', 'showCurrent'];
982
+
983
+ dataLabelOptionsProperties.forEach((property) => {
984
+ describe(`when ChartDataLabelsOptions.${property} is true`, () => {
985
+ it(`should have an datalabel propery in dataset`, () => {
986
+ chartJSService.setDataLabelOptions({ [property]: true });
987
+ const result = chartJSService.addDataLabelsData(deepCopy(data));
988
+ expect(
989
+ (result[0] as ChartJSDataset).data.find((item: any) => item.datalabel)
990
+ ).toBeTruthy();
991
+ });
992
+ });
993
+ });
994
+
995
+ describe('when neither ChartDataLabelsOptions.showMin, showMax, showCurrent is true', () => {
996
+ it('should NOT have an datalabel propery in dataset', () => {
997
+ chartJSService.setDataLabelOptions({});
998
+
999
+ const result = chartJSService.addDataLabelsData(deepCopy(data));
1000
+ expect((result[0] as ChartJSDataset).data.find((item: any) => item.datalabel)).toBeFalsy();
1001
+ });
1002
+ });
1003
+ });
1004
+ });