@weeehaoooz/talos-ui 0.1.1 → 0.1.2

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 (190) hide show
  1. package/README.md +2 -0
  2. package/fesm2022/{weeehaoooz-talos-ui-button-button-group.mjs → weeehaoooz-talos-ui-button.mjs} +91 -15
  3. package/fesm2022/weeehaoooz-talos-ui-button.mjs.map +1 -0
  4. package/fesm2022/weeehaoooz-talos-ui-data-display.mjs +3110 -0
  5. package/fesm2022/weeehaoooz-talos-ui-data-display.mjs.map +1 -0
  6. package/fesm2022/weeehaoooz-talos-ui-data-viz.mjs +2414 -0
  7. package/fesm2022/weeehaoooz-talos-ui-data-viz.mjs.map +1 -0
  8. package/fesm2022/weeehaoooz-talos-ui-dropdown.mjs +1039 -0
  9. package/fesm2022/weeehaoooz-talos-ui-dropdown.mjs.map +1 -0
  10. package/fesm2022/weeehaoooz-talos-ui-feedback.mjs +2885 -0
  11. package/fesm2022/weeehaoooz-talos-ui-feedback.mjs.map +1 -0
  12. package/fesm2022/weeehaoooz-talos-ui-form.mjs +10799 -0
  13. package/fesm2022/weeehaoooz-talos-ui-form.mjs.map +1 -0
  14. package/fesm2022/weeehaoooz-talos-ui-layout.mjs +1316 -7
  15. package/fesm2022/weeehaoooz-talos-ui-layout.mjs.map +1 -1
  16. package/fesm2022/weeehaoooz-talos-ui-nav.mjs +3 -3
  17. package/fesm2022/weeehaoooz-talos-ui-nav.mjs.map +1 -1
  18. package/fesm2022/weeehaoooz-talos-ui.mjs +21592 -16293
  19. package/fesm2022/weeehaoooz-talos-ui.mjs.map +1 -1
  20. package/package.json +20 -139
  21. package/styles/_breadcrumb.scss +16 -0
  22. package/styles/_button-group.scss +2 -1
  23. package/styles/_buttons.scss +51 -0
  24. package/styles/_dropdown.scss +438 -0
  25. package/styles/_form-controls.scss +13 -0
  26. package/styles/_progress-bar.scss +43 -0
  27. package/styles/_skeleton.scss +176 -0
  28. package/styles/_spinner.scss +58 -0
  29. package/styles/_variables.scss +33 -0
  30. package/styles/index.scss +6 -1
  31. package/types/weeehaoooz-talos-ui-button.d.ts +92 -0
  32. package/types/weeehaoooz-talos-ui-button.d.ts.map +1 -0
  33. package/types/weeehaoooz-talos-ui-data-display.d.ts +1018 -0
  34. package/types/weeehaoooz-talos-ui-data-display.d.ts.map +1 -0
  35. package/types/weeehaoooz-talos-ui-data-viz.d.ts +839 -0
  36. package/types/weeehaoooz-talos-ui-data-viz.d.ts.map +1 -0
  37. package/types/weeehaoooz-talos-ui-dropdown.d.ts +187 -0
  38. package/types/weeehaoooz-talos-ui-dropdown.d.ts.map +1 -0
  39. package/types/weeehaoooz-talos-ui-feedback.d.ts +1495 -0
  40. package/types/weeehaoooz-talos-ui-feedback.d.ts.map +1 -0
  41. package/types/weeehaoooz-talos-ui-form.d.ts +2639 -0
  42. package/types/weeehaoooz-talos-ui-form.d.ts.map +1 -0
  43. package/types/weeehaoooz-talos-ui-layout.d.ts +851 -3
  44. package/types/weeehaoooz-talos-ui-layout.d.ts.map +1 -1
  45. package/types/weeehaoooz-talos-ui-nav.d.ts +1 -1
  46. package/types/weeehaoooz-talos-ui.d.ts +7148 -4629
  47. package/types/weeehaoooz-talos-ui.d.ts.map +1 -1
  48. package/fesm2022/weeehaoooz-talos-ui-button-button-group.mjs.map +0 -1
  49. package/fesm2022/weeehaoooz-talos-ui-button-button.mjs +0 -94
  50. package/fesm2022/weeehaoooz-talos-ui-button-button.mjs.map +0 -1
  51. package/fesm2022/weeehaoooz-talos-ui-data-display-badge.mjs +0 -233
  52. package/fesm2022/weeehaoooz-talos-ui-data-display-badge.mjs.map +0 -1
  53. package/fesm2022/weeehaoooz-talos-ui-data-display-data-grid.mjs +0 -1627
  54. package/fesm2022/weeehaoooz-talos-ui-data-display-data-grid.mjs.map +0 -1
  55. package/fesm2022/weeehaoooz-talos-ui-data-display-status-tag.mjs +0 -361
  56. package/fesm2022/weeehaoooz-talos-ui-data-display-status-tag.mjs.map +0 -1
  57. package/fesm2022/weeehaoooz-talos-ui-data-display-timeline.mjs +0 -312
  58. package/fesm2022/weeehaoooz-talos-ui-data-display-timeline.mjs.map +0 -1
  59. package/fesm2022/weeehaoooz-talos-ui-data-display-trend-indicator.mjs +0 -235
  60. package/fesm2022/weeehaoooz-talos-ui-data-display-trend-indicator.mjs.map +0 -1
  61. package/fesm2022/weeehaoooz-talos-ui-data-viz-category-bar.mjs +0 -462
  62. package/fesm2022/weeehaoooz-talos-ui-data-viz-category-bar.mjs.map +0 -1
  63. package/fesm2022/weeehaoooz-talos-ui-data-viz-heatmap.mjs +0 -805
  64. package/fesm2022/weeehaoooz-talos-ui-data-viz-heatmap.mjs.map +0 -1
  65. package/fesm2022/weeehaoooz-talos-ui-data-viz-mini-donut.mjs +0 -267
  66. package/fesm2022/weeehaoooz-talos-ui-data-viz-mini-donut.mjs.map +0 -1
  67. package/fesm2022/weeehaoooz-talos-ui-data-viz-mini-gauge.mjs +0 -351
  68. package/fesm2022/weeehaoooz-talos-ui-data-viz-mini-gauge.mjs.map +0 -1
  69. package/fesm2022/weeehaoooz-talos-ui-data-viz-sparkline.mjs +0 -566
  70. package/fesm2022/weeehaoooz-talos-ui-data-viz-sparkline.mjs.map +0 -1
  71. package/fesm2022/weeehaoooz-talos-ui-feedback-alert.mjs +0 -534
  72. package/fesm2022/weeehaoooz-talos-ui-feedback-alert.mjs.map +0 -1
  73. package/fesm2022/weeehaoooz-talos-ui-feedback-dialog.mjs +0 -446
  74. package/fesm2022/weeehaoooz-talos-ui-feedback-dialog.mjs.map +0 -1
  75. package/fesm2022/weeehaoooz-talos-ui-feedback-snackbar.mjs +0 -376
  76. package/fesm2022/weeehaoooz-talos-ui-feedback-snackbar.mjs.map +0 -1
  77. package/fesm2022/weeehaoooz-talos-ui-feedback-tooltip.mjs +0 -147
  78. package/fesm2022/weeehaoooz-talos-ui-feedback-tooltip.mjs.map +0 -1
  79. package/fesm2022/weeehaoooz-talos-ui-form-affix.mjs +0 -242
  80. package/fesm2022/weeehaoooz-talos-ui-form-affix.mjs.map +0 -1
  81. package/fesm2022/weeehaoooz-talos-ui-form-autocomplete.mjs +0 -514
  82. package/fesm2022/weeehaoooz-talos-ui-form-autocomplete.mjs.map +0 -1
  83. package/fesm2022/weeehaoooz-talos-ui-form-checkbox.mjs +0 -548
  84. package/fesm2022/weeehaoooz-talos-ui-form-checkbox.mjs.map +0 -1
  85. package/fesm2022/weeehaoooz-talos-ui-form-chips.mjs +0 -692
  86. package/fesm2022/weeehaoooz-talos-ui-form-chips.mjs.map +0 -1
  87. package/fesm2022/weeehaoooz-talos-ui-form-color-picker.mjs +0 -761
  88. package/fesm2022/weeehaoooz-talos-ui-form-color-picker.mjs.map +0 -1
  89. package/fesm2022/weeehaoooz-talos-ui-form-date-picker.mjs +0 -896
  90. package/fesm2022/weeehaoooz-talos-ui-form-date-picker.mjs.map +0 -1
  91. package/fesm2022/weeehaoooz-talos-ui-form-date-range-picker.mjs +0 -872
  92. package/fesm2022/weeehaoooz-talos-ui-form-date-range-picker.mjs.map +0 -1
  93. package/fesm2022/weeehaoooz-talos-ui-form-date-time-picker.mjs +0 -119
  94. package/fesm2022/weeehaoooz-talos-ui-form-date-time-picker.mjs.map +0 -1
  95. package/fesm2022/weeehaoooz-talos-ui-form-date-time-range-picker.mjs +0 -135
  96. package/fesm2022/weeehaoooz-talos-ui-form-date-time-range-picker.mjs.map +0 -1
  97. package/fesm2022/weeehaoooz-talos-ui-form-drop-zone.mjs +0 -666
  98. package/fesm2022/weeehaoooz-talos-ui-form-drop-zone.mjs.map +0 -1
  99. package/fesm2022/weeehaoooz-talos-ui-form-form-field.mjs +0 -147
  100. package/fesm2022/weeehaoooz-talos-ui-form-form-field.mjs.map +0 -1
  101. package/fesm2022/weeehaoooz-talos-ui-form-input.mjs +0 -33
  102. package/fesm2022/weeehaoooz-talos-ui-form-input.mjs.map +0 -1
  103. package/fesm2022/weeehaoooz-talos-ui-form-otp.mjs +0 -455
  104. package/fesm2022/weeehaoooz-talos-ui-form-otp.mjs.map +0 -1
  105. package/fesm2022/weeehaoooz-talos-ui-form-password-input.mjs +0 -379
  106. package/fesm2022/weeehaoooz-talos-ui-form-password-input.mjs.map +0 -1
  107. package/fesm2022/weeehaoooz-talos-ui-form-radio.mjs +0 -297
  108. package/fesm2022/weeehaoooz-talos-ui-form-radio.mjs.map +0 -1
  109. package/fesm2022/weeehaoooz-talos-ui-form-range-input.mjs +0 -661
  110. package/fesm2022/weeehaoooz-talos-ui-form-range-input.mjs.map +0 -1
  111. package/fesm2022/weeehaoooz-talos-ui-form-rating.mjs +0 -346
  112. package/fesm2022/weeehaoooz-talos-ui-form-rating.mjs.map +0 -1
  113. package/fesm2022/weeehaoooz-talos-ui-form-select-input.mjs +0 -896
  114. package/fesm2022/weeehaoooz-talos-ui-form-select-input.mjs.map +0 -1
  115. package/fesm2022/weeehaoooz-talos-ui-form-slide-toggle.mjs +0 -252
  116. package/fesm2022/weeehaoooz-talos-ui-form-slide-toggle.mjs.map +0 -1
  117. package/fesm2022/weeehaoooz-talos-ui-form-transfer-list.mjs +0 -916
  118. package/fesm2022/weeehaoooz-talos-ui-form-transfer-list.mjs.map +0 -1
  119. package/types/weeehaoooz-talos-ui-button-button-group.d.ts +0 -62
  120. package/types/weeehaoooz-talos-ui-button-button-group.d.ts.map +0 -1
  121. package/types/weeehaoooz-talos-ui-button-button.d.ts +0 -38
  122. package/types/weeehaoooz-talos-ui-button-button.d.ts.map +0 -1
  123. package/types/weeehaoooz-talos-ui-data-display-badge.d.ts +0 -119
  124. package/types/weeehaoooz-talos-ui-data-display-badge.d.ts.map +0 -1
  125. package/types/weeehaoooz-talos-ui-data-display-data-grid.d.ts +0 -272
  126. package/types/weeehaoooz-talos-ui-data-display-data-grid.d.ts.map +0 -1
  127. package/types/weeehaoooz-talos-ui-data-display-status-tag.d.ts +0 -135
  128. package/types/weeehaoooz-talos-ui-data-display-status-tag.d.ts.map +0 -1
  129. package/types/weeehaoooz-talos-ui-data-display-timeline.d.ts +0 -144
  130. package/types/weeehaoooz-talos-ui-data-display-timeline.d.ts.map +0 -1
  131. package/types/weeehaoooz-talos-ui-data-display-trend-indicator.d.ts +0 -83
  132. package/types/weeehaoooz-talos-ui-data-display-trend-indicator.d.ts.map +0 -1
  133. package/types/weeehaoooz-talos-ui-data-viz-category-bar.d.ts +0 -255
  134. package/types/weeehaoooz-talos-ui-data-viz-category-bar.d.ts.map +0 -1
  135. package/types/weeehaoooz-talos-ui-data-viz-heatmap.d.ts +0 -204
  136. package/types/weeehaoooz-talos-ui-data-viz-heatmap.d.ts.map +0 -1
  137. package/types/weeehaoooz-talos-ui-data-viz-mini-donut.d.ts +0 -101
  138. package/types/weeehaoooz-talos-ui-data-viz-mini-donut.d.ts.map +0 -1
  139. package/types/weeehaoooz-talos-ui-data-viz-mini-gauge.d.ts +0 -138
  140. package/types/weeehaoooz-talos-ui-data-viz-mini-gauge.d.ts.map +0 -1
  141. package/types/weeehaoooz-talos-ui-data-viz-sparkline.d.ts +0 -161
  142. package/types/weeehaoooz-talos-ui-data-viz-sparkline.d.ts.map +0 -1
  143. package/types/weeehaoooz-talos-ui-feedback-alert.d.ts +0 -212
  144. package/types/weeehaoooz-talos-ui-feedback-alert.d.ts.map +0 -1
  145. package/types/weeehaoooz-talos-ui-feedback-dialog.d.ts +0 -259
  146. package/types/weeehaoooz-talos-ui-feedback-dialog.d.ts.map +0 -1
  147. package/types/weeehaoooz-talos-ui-feedback-snackbar.d.ts +0 -147
  148. package/types/weeehaoooz-talos-ui-feedback-snackbar.d.ts.map +0 -1
  149. package/types/weeehaoooz-talos-ui-feedback-tooltip.d.ts +0 -32
  150. package/types/weeehaoooz-talos-ui-feedback-tooltip.d.ts.map +0 -1
  151. package/types/weeehaoooz-talos-ui-form-affix.d.ts +0 -88
  152. package/types/weeehaoooz-talos-ui-form-affix.d.ts.map +0 -1
  153. package/types/weeehaoooz-talos-ui-form-autocomplete.d.ts +0 -113
  154. package/types/weeehaoooz-talos-ui-form-autocomplete.d.ts.map +0 -1
  155. package/types/weeehaoooz-talos-ui-form-checkbox.d.ts +0 -165
  156. package/types/weeehaoooz-talos-ui-form-checkbox.d.ts.map +0 -1
  157. package/types/weeehaoooz-talos-ui-form-chips.d.ts +0 -152
  158. package/types/weeehaoooz-talos-ui-form-chips.d.ts.map +0 -1
  159. package/types/weeehaoooz-talos-ui-form-color-picker.d.ts +0 -144
  160. package/types/weeehaoooz-talos-ui-form-color-picker.d.ts.map +0 -1
  161. package/types/weeehaoooz-talos-ui-form-date-picker.d.ts +0 -138
  162. package/types/weeehaoooz-talos-ui-form-date-picker.d.ts.map +0 -1
  163. package/types/weeehaoooz-talos-ui-form-date-range-picker.d.ts +0 -148
  164. package/types/weeehaoooz-talos-ui-form-date-range-picker.d.ts.map +0 -1
  165. package/types/weeehaoooz-talos-ui-form-date-time-picker.d.ts +0 -44
  166. package/types/weeehaoooz-talos-ui-form-date-time-picker.d.ts.map +0 -1
  167. package/types/weeehaoooz-talos-ui-form-date-time-range-picker.d.ts +0 -48
  168. package/types/weeehaoooz-talos-ui-form-date-time-range-picker.d.ts.map +0 -1
  169. package/types/weeehaoooz-talos-ui-form-drop-zone.d.ts +0 -227
  170. package/types/weeehaoooz-talos-ui-form-drop-zone.d.ts.map +0 -1
  171. package/types/weeehaoooz-talos-ui-form-form-field.d.ts +0 -42
  172. package/types/weeehaoooz-talos-ui-form-form-field.d.ts.map +0 -1
  173. package/types/weeehaoooz-talos-ui-form-input.d.ts +0 -15
  174. package/types/weeehaoooz-talos-ui-form-input.d.ts.map +0 -1
  175. package/types/weeehaoooz-talos-ui-form-otp.d.ts +0 -111
  176. package/types/weeehaoooz-talos-ui-form-otp.d.ts.map +0 -1
  177. package/types/weeehaoooz-talos-ui-form-password-input.d.ts +0 -145
  178. package/types/weeehaoooz-talos-ui-form-password-input.d.ts.map +0 -1
  179. package/types/weeehaoooz-talos-ui-form-radio.d.ts +0 -84
  180. package/types/weeehaoooz-talos-ui-form-radio.d.ts.map +0 -1
  181. package/types/weeehaoooz-talos-ui-form-range-input.d.ts +0 -181
  182. package/types/weeehaoooz-talos-ui-form-range-input.d.ts.map +0 -1
  183. package/types/weeehaoooz-talos-ui-form-rating.d.ts +0 -110
  184. package/types/weeehaoooz-talos-ui-form-rating.d.ts.map +0 -1
  185. package/types/weeehaoooz-talos-ui-form-select-input.d.ts +0 -195
  186. package/types/weeehaoooz-talos-ui-form-select-input.d.ts.map +0 -1
  187. package/types/weeehaoooz-talos-ui-form-slide-toggle.d.ts +0 -79
  188. package/types/weeehaoooz-talos-ui-form-slide-toggle.d.ts.map +0 -1
  189. package/types/weeehaoooz-talos-ui-form-transfer-list.d.ts +0 -192
  190. package/types/weeehaoooz-talos-ui-form-transfer-list.d.ts.map +0 -1
@@ -1,805 +0,0 @@
1
- import * as i0 from '@angular/core';
2
- import { inject, ElementRef, input, model, output, signal, computed, effect, Component, NgModule } from '@angular/core';
3
- import * as i1 from '@angular/forms';
4
- import { FormsModule } from '@angular/forms';
5
- import { LucideRefreshCw, LucideUpload, LucideMaximize2, LucideMinimize2, LucideChevronDown, LucideCheck, LucideFileSpreadsheet, LucideFileJson, LucideCalendar, LucideClock, LucideArrowLeftRight } from '@lucide/angular';
6
- import { startOfDay, endOfDay, startOfISOWeek, subWeeks, endOfISOWeek, isSameDay, isBefore, addDays, addWeeks, isValid } from 'date-fns';
7
- import { formatDate } from '@weeehaoooz/talos-ui/core';
8
- import { DateRangePickerComponent } from '@weeehaoooz/talos-ui/form/date-range-picker';
9
- import { TalosTooltipDirective } from '@weeehaoooz/talos-ui/feedback/tooltip';
10
-
11
- const DEFAULT_DAYS = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
12
- const PALETTE_CONFIG = {
13
- indigo: {
14
- zero: { bg: '#eef2ff', text: '#4338ca' },
15
- min: { r: 219, g: 228, b: 255 }, // #dbe4ff
16
- max: { r: 67, g: 56, b: 202 }, // #4338ca
17
- gradientCss: 'linear-gradient(90deg, #dbe4ff 0%, #818cf8 50%, #4338ca 100%)'
18
- },
19
- blue: {
20
- zero: { bg: '#eff6ff', text: '#1d4ed8' },
21
- min: { r: 219, g: 234, b: 254 }, // #dbeafe
22
- max: { r: 29, g: 78, b: 216 }, // #1d4ed8
23
- gradientCss: 'linear-gradient(90deg, #dbeafe 0%, #60a5fa 50%, #1d4ed8 100%)'
24
- },
25
- emerald: {
26
- zero: { bg: '#ecfdf5', text: '#047857' },
27
- min: { r: 209, g: 250, b: 229 }, // #d1fae5
28
- max: { r: 4, g: 120, b: 87 }, // #047857
29
- gradientCss: 'linear-gradient(90deg, #d1fae5 0%, #34d399 50%, #047857 100%)'
30
- },
31
- rose: {
32
- zero: { bg: '#fff1f2', text: '#be123c' },
33
- min: { r: 255, g: 228, b: 230 }, // #ffe4e6
34
- max: { r: 190, g: 18, b: 60 }, // #be123c
35
- gradientCss: 'linear-gradient(90deg, #ffe4e6 0%, #fb7185 50%, #be123c 100%)'
36
- },
37
- amber: {
38
- zero: { bg: '#fffbeb', text: '#b45309' },
39
- min: { r: 254, g: 243, b: 199 }, // #fef3c7
40
- max: { r: 180, g: 83, b: 9 }, // #b45309
41
- gradientCss: 'linear-gradient(90deg, #fef3c7 0%, #fbbf24 50%, #b45309 100%)'
42
- },
43
- violet: {
44
- zero: { bg: '#f5f3ff', text: '#6d28d9' },
45
- min: { r: 237, g: 233, b: 254 }, // #ede9fe
46
- max: { r: 109, g: 40, b: 217 }, // #6d28d9
47
- gradientCss: 'linear-gradient(90deg, #ede9fe 0%, #a78bfa 50%, #6d28d9 100%)'
48
- },
49
- slate: {
50
- zero: { bg: '#f8fafc', text: '#334155' },
51
- min: { r: 226, g: 232, b: 240 }, // #e2e8f0
52
- max: { r: 51, g: 65, b: 85 }, // #334155
53
- gradientCss: 'linear-gradient(90deg, #e2e8f0 0%, #94a3b8 50%, #334155 100%)'
54
- },
55
- custom: {
56
- zero: { bg: '#eef2ff', text: '#4338ca' },
57
- min: { r: 219, g: 228, b: 255 },
58
- max: { r: 67, g: 56, b: 202 },
59
- gradientCss: 'linear-gradient(90deg, #dbe4ff 0%, #4338ca 100%)'
60
- }
61
- };
62
- class TalosHeatmapComponent {
63
- elementRef = inject(ElementRef);
64
- // Inputs & Models
65
- data = input([], /* @ts-ignore */
66
- ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
67
- metrics = input([], /* @ts-ignore */
68
- ...(ngDevMode ? [{ debugName: "metrics" }] : /* istanbul ignore next */ []));
69
- selectedMetricId = model(undefined, /* @ts-ignore */
70
- ...(ngDevMode ? [{ debugName: "selectedMetricId" }] : /* istanbul ignore next */ []));
71
- interval = model('hour', /* @ts-ignore */
72
- ...(ngDevMode ? [{ debugName: "interval" }] : /* istanbul ignore next */ []));
73
- dateRange = model(null, /* @ts-ignore */
74
- ...(ngDevMode ? [{ debugName: "dateRange" }] : /* istanbul ignore next */ []));
75
- swapAxes = model(false, /* @ts-ignore */
76
- ...(ngDevMode ? [{ debugName: "swapAxes" }] : /* istanbul ignore next */ []));
77
- title = input('Busiest times', /* @ts-ignore */
78
- ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
79
- hoursRange = input([9, 17], /* @ts-ignore */
80
- ...(ngDevMode ? [{ debugName: "hoursRange" }] : /* istanbul ignore next */ []));
81
- timeFormat = input('12h', /* @ts-ignore */
82
- ...(ngDevMode ? [{ debugName: "timeFormat" }] : /* istanbul ignore next */ []));
83
- days = input(DEFAULT_DAYS, /* @ts-ignore */
84
- ...(ngDevMode ? [{ debugName: "days" }] : /* istanbul ignore next */ []));
85
- colorScheme = input('indigo', /* @ts-ignore */
86
- ...(ngDevMode ? [{ debugName: "colorScheme" }] : /* istanbul ignore next */ []));
87
- customColorStops = input(undefined, /* @ts-ignore */
88
- ...(ngDevMode ? [{ debugName: "customColorStops" }] : /* istanbul ignore next */ []));
89
- showLegend = input(true, /* @ts-ignore */
90
- ...(ngDevMode ? [{ debugName: "showLegend" }] : /* istanbul ignore next */ []));
91
- showValues = input(true, /* @ts-ignore */
92
- ...(ngDevMode ? [{ debugName: "showValues" }] : /* istanbul ignore next */ []));
93
- cellShape = input('pill', /* @ts-ignore */
94
- ...(ngDevMode ? [{ debugName: "cellShape" }] : /* istanbul ignore next */ []));
95
- cellSize = input('md', /* @ts-ignore */
96
- ...(ngDevMode ? [{ debugName: "cellSize" }] : /* istanbul ignore next */ []));
97
- fitWidth = input(undefined, /* @ts-ignore */
98
- ...(ngDevMode ? [{ debugName: "fitWidth" }] : /* istanbul ignore next */ []));
99
- loading = input(false, /* @ts-ignore */
100
- ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
101
- showToolbar = input(true, /* @ts-ignore */
102
- ...(ngDevMode ? [{ debugName: "showToolbar" }] : /* istanbul ignore next */ []));
103
- showRefresh = input(true, /* @ts-ignore */
104
- ...(ngDevMode ? [{ debugName: "showRefresh" }] : /* istanbul ignore next */ []));
105
- showExport = input(true, /* @ts-ignore */
106
- ...(ngDevMode ? [{ debugName: "showExport" }] : /* istanbul ignore next */ []));
107
- showExpand = input(true, /* @ts-ignore */
108
- ...(ngDevMode ? [{ debugName: "showExpand" }] : /* istanbul ignore next */ []));
109
- showSwapAxes = input(false, /* @ts-ignore */
110
- ...(ngDevMode ? [{ debugName: "showSwapAxes" }] : /* istanbul ignore next */ []));
111
- showIntervalToggle = input(false, /* @ts-ignore */
112
- ...(ngDevMode ? [{ debugName: "showIntervalToggle" }] : /* istanbul ignore next */ []));
113
- showDateRangePicker = input(false, /* @ts-ignore */
114
- ...(ngDevMode ? [{ debugName: "showDateRangePicker" }] : /* istanbul ignore next */ []));
115
- dateRangePresets = input(null, /* @ts-ignore */
116
- ...(ngDevMode ? [{ debugName: "dateRangePresets" }] : /* istanbul ignore next */ []));
117
- unit = input('', /* @ts-ignore */
118
- ...(ngDevMode ? [{ debugName: "unit" }] : /* istanbul ignore next */ []));
119
- maxValue = input(undefined, /* @ts-ignore */
120
- ...(ngDevMode ? [{ debugName: "maxValue" }] : /* istanbul ignore next */ []));
121
- minValue = input(undefined, /* @ts-ignore */
122
- ...(ngDevMode ? [{ debugName: "minValue" }] : /* istanbul ignore next */ []));
123
- // Outputs
124
- cellClick = output();
125
- cellHover = output();
126
- timeRangeChange = output();
127
- refresh = output();
128
- metricChange = output();
129
- export = output();
130
- // State signals
131
- isExpanded = signal(false, /* @ts-ignore */
132
- ...(ngDevMode ? [{ debugName: "isExpanded" }] : /* istanbul ignore next */ []));
133
- isMetricDropdownOpen = signal(false, /* @ts-ignore */
134
- ...(ngDevMode ? [{ debugName: "isMetricDropdownOpen" }] : /* istanbul ignore next */ []));
135
- isExportDropdownOpen = signal(false, /* @ts-ignore */
136
- ...(ngDevMode ? [{ debugName: "isExportDropdownOpen" }] : /* istanbul ignore next */ []));
137
- hoveredCell = signal(null, /* @ts-ignore */
138
- ...(ngDevMode ? [{ debugName: "hoveredCell" }] : /* istanbul ignore next */ []));
139
- focusedCoord = signal(null, /* @ts-ignore */
140
- ...(ngDevMode ? [{ debugName: "focusedCoord" }] : /* istanbul ignore next */ []));
141
- // Layout Fit computation
142
- isFitWidth = computed(() => {
143
- const fw = this.fitWidth();
144
- if (fw !== undefined)
145
- return fw;
146
- return this.cellShape() !== 'square';
147
- }, /* @ts-ignore */
148
- ...(ngDevMode ? [{ debugName: "isFitWidth" }] : /* istanbul ignore next */ []));
149
- // Active Metric computation
150
- currentMetric = computed(() => {
151
- const list = this.metrics();
152
- if (!list || list.length === 0)
153
- return undefined;
154
- const selectedId = this.selectedMetricId();
155
- if (selectedId) {
156
- const found = list.find((m) => m.id === selectedId);
157
- if (found)
158
- return found;
159
- }
160
- return list[0];
161
- }, /* @ts-ignore */
162
- ...(ngDevMode ? [{ debugName: "currentMetric" }] : /* istanbul ignore next */ []));
163
- // Effective Active Color Scheme
164
- activeColorScheme = computed(() => {
165
- const metric = this.currentMetric();
166
- if (metric && metric.colorScheme)
167
- return metric.colorScheme;
168
- return this.colorScheme();
169
- }, /* @ts-ignore */
170
- ...(ngDevMode ? [{ debugName: "activeColorScheme" }] : /* istanbul ignore next */ []));
171
- // Effective Unit
172
- activeUnit = computed(() => {
173
- const metric = this.currentMetric();
174
- if (metric && metric.unit !== undefined)
175
- return metric.unit;
176
- return this.unit();
177
- }, /* @ts-ignore */
178
- ...(ngDevMode ? [{ debugName: "activeUnit" }] : /* istanbul ignore next */ []));
179
- // Effective Raw Data Input
180
- activeDataInput = computed(() => {
181
- const metric = this.currentMetric();
182
- if (metric)
183
- return metric.data;
184
- return this.data();
185
- }, /* @ts-ignore */
186
- ...(ngDevMode ? [{ debugName: "activeDataInput" }] : /* istanbul ignore next */ []));
187
- // Hours array from range (for hour-by-hour mode)
188
- hours = computed(() => {
189
- const [start, end] = this.hoursRange();
190
- const clampedStart = Math.max(0, Math.min(23, start));
191
- const clampedEnd = Math.max(clampedStart, Math.min(23, end));
192
- const result = [];
193
- for (let h = clampedStart; h <= clampedEnd; h++) {
194
- result.push(h);
195
- }
196
- return result;
197
- }, /* @ts-ignore */
198
- ...(ngDevMode ? [{ debugName: "hours" }] : /* istanbul ignore next */ []));
199
- // Resolved Date Range bounds
200
- parsedDateRange = computed(() => {
201
- const dr = this.dateRange();
202
- if (!dr || (!dr.startDate && !dr.endDate)) {
203
- return { start: null, end: null };
204
- }
205
- const s = dr.startDate ? startOfDay(new Date(dr.startDate)) : null;
206
- const e = dr.endDate ? endOfDay(new Date(dr.endDate)) : (s ? endOfDay(s) : null);
207
- return { start: s, end: e };
208
- }, /* @ts-ignore */
209
- ...(ngDevMode ? [{ debugName: "parsedDateRange" }] : /* istanbul ignore next */ []));
210
- // Day list for Day-by-Day mode (weeks grouping)
211
- dayModeWeeks = computed(() => {
212
- const { start, end } = this.parsedDateRange();
213
- const effectiveStart = start || startOfISOWeek(subWeeks(new Date(), 3));
214
- const effectiveEnd = end || endOfISOWeek(new Date());
215
- const weeks = [];
216
- let currentWeekStart = startOfISOWeek(effectiveStart);
217
- const lastWeekEnd = endOfISOWeek(effectiveEnd);
218
- while (isSameDay(currentWeekStart, lastWeekEnd) || isBefore(currentWeekStart, lastWeekEnd)) {
219
- const currentWeekEnd = addDays(currentWeekStart, 6);
220
- const daysInWeek = [];
221
- for (let i = 0; i < 7; i++) {
222
- daysInWeek.push(addDays(currentWeekStart, i));
223
- }
224
- const label = `${formatDate(currentWeekStart, 'MMM d')} - ${formatDate(currentWeekEnd, 'MMM d')}`;
225
- weeks.push({
226
- label,
227
- start: currentWeekStart,
228
- end: currentWeekEnd,
229
- days: daysInWeek
230
- });
231
- currentWeekStart = addWeeks(currentWeekStart, 1);
232
- }
233
- return weeks;
234
- }, /* @ts-ignore */
235
- ...(ngDevMode ? [{ debugName: "dayModeWeeks" }] : /* istanbul ignore next */ []));
236
- // Normalized Value Map:
237
- // For 'hour': Map<`${colKey}_${hour}`, { value, meta }>
238
- // For 'day': Map<`${yyyy-MM-dd}`, { value, meta }> AND Map<`${colKey}`, { value, meta }>
239
- normalizedValueMap = computed(() => {
240
- const map = new Map();
241
- const rawInput = this.activeDataInput();
242
- const currentDays = this.days();
243
- const currentInterval = this.interval();
244
- if (!rawInput)
245
- return map;
246
- if (Array.isArray(rawInput)) {
247
- if (rawInput.length === 0)
248
- return map;
249
- const firstItem = rawInput[0];
250
- if (typeof firstItem === 'string' ||
251
- firstItem instanceof Date ||
252
- (typeof firstItem === 'number' && firstItem > 1000000000)) {
253
- // Raw Timestamp list
254
- rawInput.forEach((ts) => {
255
- const date = new Date(ts);
256
- if (isValid(date)) {
257
- if (currentInterval === 'day') {
258
- const dayKey = formatDate(date, 'yyyy-MM-dd');
259
- const existing = map.get(dayKey);
260
- if (existing)
261
- existing.value += 1;
262
- else
263
- map.set(dayKey, { value: 1 });
264
- }
265
- else {
266
- const dayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
267
- const dayName = dayNames[date.getDay()];
268
- const matchedDay = currentDays.find((d) => d.toLowerCase().startsWith(dayName.toLowerCase())) || dayName;
269
- const hour = date.getHours();
270
- const key = `${matchedDay}_${hour}`;
271
- const existing = map.get(key);
272
- if (existing)
273
- existing.value += 1;
274
- else
275
- map.set(key, { value: 1 });
276
- }
277
- }
278
- });
279
- }
280
- else {
281
- // HeatmapDataPoint array
282
- rawInput.forEach((point) => {
283
- if (currentInterval === 'day') {
284
- let dayKey = '';
285
- if (point.date) {
286
- dayKey = typeof point.date === 'string' && /^\d{4}-\d{2}-\d{2}/.test(point.date)
287
- ? point.date.substring(0, 10)
288
- : formatDate(new Date(point.date), 'yyyy-MM-dd');
289
- }
290
- else if (point.day instanceof Date) {
291
- dayKey = formatDate(point.day, 'yyyy-MM-dd');
292
- }
293
- else if (typeof point.day === 'string' && /^\d{4}-\d{2}-\d{2}/.test(point.day)) {
294
- dayKey = point.day.substring(0, 10);
295
- }
296
- else {
297
- dayKey = String(point.day ?? '');
298
- }
299
- if (dayKey) {
300
- const existing = map.get(dayKey);
301
- if (existing) {
302
- existing.value += point.value;
303
- if (point.meta)
304
- existing.meta = { ...existing.meta, ...point.meta };
305
- }
306
- else {
307
- map.set(dayKey, { value: point.value, meta: point.meta });
308
- }
309
- }
310
- }
311
- else {
312
- // Hour by hour
313
- let dayKey = '';
314
- if (point.day instanceof Date) {
315
- const dayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
316
- const dayName = dayNames[point.day.getDay()];
317
- dayKey = currentDays.find((d) => d.toLowerCase().startsWith(dayName.toLowerCase())) || dayName;
318
- }
319
- else if (typeof point.day === 'number') {
320
- dayKey = currentDays[point.day] || String(point.day);
321
- }
322
- else {
323
- dayKey = String(point.day ?? '');
324
- }
325
- const hour = point.hour ?? 0;
326
- const key = `${dayKey}_${hour}`;
327
- const existing = map.get(key);
328
- if (existing) {
329
- existing.value += point.value;
330
- if (point.meta)
331
- existing.meta = { ...existing.meta, ...point.meta };
332
- }
333
- else {
334
- map.set(key, { value: point.value, meta: point.meta });
335
- }
336
- }
337
- });
338
- }
339
- }
340
- else if (typeof rawInput === 'object') {
341
- // HeatmapMatrixData
342
- const matrix = rawInput;
343
- Object.entries(matrix).forEach(([outerKey, innerObj]) => {
344
- if (typeof innerObj === 'object' && innerObj !== null) {
345
- Object.entries(innerObj).forEach(([innerKey, val]) => {
346
- const numVal = Number(val) || 0;
347
- if (currentInterval === 'day') {
348
- const key = `${outerKey}_${innerKey}`;
349
- map.set(key, { value: numVal });
350
- }
351
- else {
352
- const isInnerHour = !isNaN(Number(innerKey));
353
- if (isInnerHour) {
354
- const hour = Number(innerKey);
355
- const key = `${outerKey}_${hour}`;
356
- map.set(key, { value: numVal });
357
- }
358
- else {
359
- const hour = Number(outerKey);
360
- const key = `${innerKey}_${hour}`;
361
- map.set(key, { value: numVal });
362
- }
363
- }
364
- });
365
- }
366
- });
367
- }
368
- return map;
369
- }, /* @ts-ignore */
370
- ...(ngDevMode ? [{ debugName: "normalizedValueMap" }] : /* istanbul ignore next */ []));
371
- // Effective min & max value for heat scale
372
- computedScaleBounds = computed(() => {
373
- const customMin = this.minValue();
374
- const customMax = this.maxValue();
375
- const map = this.normalizedValueMap();
376
- let dataMax = 0;
377
- for (const item of map.values()) {
378
- if (item.value > dataMax)
379
- dataMax = item.value;
380
- }
381
- const min = customMin !== undefined ? customMin : 0;
382
- const max = customMax !== undefined ? customMax : Math.max(1, dataMax);
383
- return { min, max };
384
- }, /* @ts-ignore */
385
- ...(ngDevMode ? [{ debugName: "computedScaleBounds" }] : /* istanbul ignore next */ []));
386
- // Gradient CSS for Legend bar
387
- legendGradientCss = computed(() => {
388
- const scheme = this.activeColorScheme();
389
- return PALETTE_CONFIG[scheme]?.gradientCss || PALETTE_CONFIG.indigo.gradientCss;
390
- }, /* @ts-ignore */
391
- ...(ngDevMode ? [{ debugName: "legendGradientCss" }] : /* istanbul ignore next */ []));
392
- // Column Headers computation (supports axis swapping)
393
- columnHeaders = computed(() => {
394
- const isSwapped = this.swapAxes();
395
- const currentInterval = this.interval();
396
- if (!isSwapped) {
397
- return this.days().map((day) => ({ key: day, label: day }));
398
- }
399
- // When axes are swapped:
400
- if (currentInterval === 'day') {
401
- const weeks = this.dayModeWeeks();
402
- return weeks.map((w) => ({ key: w.label, label: w.label }));
403
- }
404
- const hoursList = this.hours();
405
- const format = this.timeFormat();
406
- return hoursList.map((hour) => ({
407
- key: hour,
408
- label: this.formatHourLabel(hour, format)
409
- }));
410
- }, /* @ts-ignore */
411
- ...(ngDevMode ? [{ debugName: "columnHeaders" }] : /* istanbul ignore next */ []));
412
- // Grid Matrix computation
413
- gridRows = computed(() => {
414
- const currentInterval = this.interval();
415
- const isSwapped = this.swapAxes();
416
- const map = this.normalizedValueMap();
417
- const { min, max } = this.computedScaleBounds();
418
- const scheme = this.activeColorScheme();
419
- const palette = PALETTE_CONFIG[scheme] || PALETTE_CONFIG.indigo;
420
- const unitStr = this.activeUnit();
421
- const unitSuffix = unitStr ? ` ${unitStr}` : '';
422
- const format = this.timeFormat();
423
- const getVisuals = (val) => {
424
- const intensity = max > min ? Math.max(0, Math.min(1, (val - min) / (max - min))) : 0;
425
- let bgColor = '';
426
- let textColor = '';
427
- if (val === 0) {
428
- bgColor = palette.zero.bg;
429
- textColor = palette.zero.text;
430
- }
431
- else {
432
- const r = Math.round(palette.min.r + (palette.max.r - palette.min.r) * intensity);
433
- const g = Math.round(palette.min.g + (palette.max.g - palette.min.g) * intensity);
434
- const b = Math.round(palette.min.b + (palette.max.b - palette.min.b) * intensity);
435
- bgColor = `rgb(${r}, ${g}, ${b})`;
436
- textColor = intensity >= 0.55 ? '#ffffff' : palette.zero.text;
437
- }
438
- return { intensity, bgColor, textColor };
439
- };
440
- // --- DAY-BY-DAY MODE ---
441
- if (currentInterval === 'day') {
442
- const weeks = this.dayModeWeeks();
443
- const dayLabels = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
444
- if (!isSwapped) {
445
- // Standard: Rows = Weeks, Columns = Days
446
- return weeks.map((week, weekIdx) => {
447
- const cells = week.days.map((d, dayIdx) => {
448
- const dateStr = formatDate(d, 'yyyy-MM-dd');
449
- const dayName = dayLabels[dayIdx];
450
- const entry = map.get(dateStr) || map.get(`${dayName}_${weekIdx}`);
451
- const val = entry?.value ?? 0;
452
- const { intensity, bgColor, textColor } = getVisuals(val);
453
- const tooltip = `${formatDate(d, 'EEEE, MMMM d, yyyy')}: ${val}${unitSuffix}`;
454
- return {
455
- id: dateStr,
456
- colKey: dayName,
457
- colLabel: `${dayName} (${formatDate(d, 'd')})`,
458
- rowKey: week.label,
459
- rowLabel: week.label,
460
- value: val,
461
- intensity,
462
- backgroundColor: bgColor,
463
- textColor,
464
- formattedValue: String(val),
465
- tooltipText: tooltip,
466
- date: d,
467
- meta: entry?.meta
468
- };
469
- });
470
- return {
471
- key: week.label,
472
- label: week.label,
473
- cells
474
- };
475
- });
476
- }
477
- else {
478
- // Swapped: Rows = Days (Mon..Sun), Columns = Weeks
479
- return dayLabels.map((dayName, dayIdx) => {
480
- const cells = weeks.map((week, weekIdx) => {
481
- const d = week.days[dayIdx];
482
- const dateStr = formatDate(d, 'yyyy-MM-dd');
483
- const entry = map.get(dateStr) || map.get(`${dayName}_${weekIdx}`);
484
- const val = entry?.value ?? 0;
485
- const { intensity, bgColor, textColor } = getVisuals(val);
486
- const tooltip = `${formatDate(d, 'EEEE, MMMM d, yyyy')}: ${val}${unitSuffix}`;
487
- return {
488
- id: `${dateStr}_swapped`,
489
- colKey: week.label,
490
- colLabel: week.label,
491
- rowKey: dayName,
492
- rowLabel: dayName,
493
- value: val,
494
- intensity,
495
- backgroundColor: bgColor,
496
- textColor,
497
- formattedValue: String(val),
498
- tooltipText: tooltip,
499
- date: d,
500
- meta: entry?.meta
501
- };
502
- });
503
- return {
504
- key: dayName,
505
- label: dayName,
506
- cells
507
- };
508
- });
509
- }
510
- }
511
- // --- HOUR-BY-HOUR MODE ---
512
- const hoursList = this.hours();
513
- const colsList = this.days();
514
- if (!isSwapped) {
515
- // Standard: Rows = Hours, Columns = Days
516
- return hoursList.map((hour) => {
517
- const hourLabel = this.formatHourLabel(hour, format);
518
- const cells = colsList.map((col) => {
519
- const key = `${col}_${hour}`;
520
- const entry = map.get(key);
521
- const val = entry?.value ?? 0;
522
- const { intensity, bgColor, textColor } = getVisuals(val);
523
- const tooltip = `${col}, ${hourLabel}: ${val}${unitSuffix}`;
524
- return {
525
- id: key,
526
- colKey: col,
527
- colLabel: col,
528
- rowKey: hour,
529
- rowLabel: hourLabel,
530
- value: val,
531
- intensity,
532
- backgroundColor: bgColor,
533
- textColor,
534
- formattedValue: String(val),
535
- tooltipText: tooltip,
536
- meta: entry?.meta
537
- };
538
- });
539
- return {
540
- key: hour,
541
- label: hourLabel,
542
- cells
543
- };
544
- });
545
- }
546
- else {
547
- // Swapped: Rows = Days, Columns = Hours
548
- return colsList.map((day) => {
549
- const cells = hoursList.map((hour) => {
550
- const hourLabel = this.formatHourLabel(hour, format);
551
- const key = `${day}_${hour}`;
552
- const entry = map.get(key);
553
- const val = entry?.value ?? 0;
554
- const { intensity, bgColor, textColor } = getVisuals(val);
555
- const tooltip = `${day}, ${hourLabel}: ${val}${unitSuffix}`;
556
- return {
557
- id: `${key}_swapped`,
558
- colKey: hour,
559
- colLabel: hourLabel,
560
- rowKey: day,
561
- rowLabel: day,
562
- value: val,
563
- intensity,
564
- backgroundColor: bgColor,
565
- textColor,
566
- formattedValue: String(val),
567
- tooltipText: tooltip,
568
- meta: entry?.meta
569
- };
570
- });
571
- return {
572
- key: day,
573
- label: day,
574
- cells
575
- };
576
- });
577
- }
578
- }, /* @ts-ignore */
579
- ...(ngDevMode ? [{ debugName: "gridRows" }] : /* istanbul ignore next */ []));
580
- constructor() {
581
- // Notify parent on time range boundaries changes
582
- effect(() => {
583
- const days = this.days();
584
- const hours = this.hours();
585
- const inter = this.interval();
586
- const dr = this.dateRange();
587
- const swapped = this.swapAxes();
588
- this.timeRangeChange.emit({
589
- interval: inter,
590
- startHour: hours.length > 0 ? hours[0] : undefined,
591
- endHour: hours.length > 0 ? hours[hours.length - 1] : undefined,
592
- days,
593
- startDate: dr?.startDate ? new Date(dr.startDate) : undefined,
594
- endDate: dr?.endDate ? new Date(dr.endDate) : undefined,
595
- dateRange: dr,
596
- swapAxes: swapped
597
- });
598
- });
599
- // Close dropdowns on outside click
600
- if (typeof document !== 'undefined') {
601
- document.addEventListener('click', (event) => {
602
- const target = event.target;
603
- if (!this.elementRef.nativeElement.contains(target)) {
604
- this.isMetricDropdownOpen.set(false);
605
- this.isExportDropdownOpen.set(false);
606
- }
607
- });
608
- }
609
- }
610
- formatHourLabel(hour, format) {
611
- if (format === '24h') {
612
- return `${hour.toString().padStart(2, '0')}:00`;
613
- }
614
- if (hour === 0)
615
- return '12 AM';
616
- if (hour < 12)
617
- return `${hour} AM`;
618
- if (hour === 12)
619
- return '12 PM';
620
- return `${hour - 12} PM`;
621
- }
622
- setInterval(newInterval) {
623
- this.interval.set(newInterval);
624
- }
625
- toggleSwapAxes() {
626
- this.swapAxes.update((v) => !v);
627
- }
628
- onDateRangePickerChange(val) {
629
- this.dateRange.set(val);
630
- }
631
- toggleExpand() {
632
- this.isExpanded.update((v) => !v);
633
- }
634
- toggleMetricDropdown(event) {
635
- event.stopPropagation();
636
- this.isMetricDropdownOpen.update((v) => !v);
637
- this.isExportDropdownOpen.set(false);
638
- }
639
- toggleExportDropdown(event) {
640
- event.stopPropagation();
641
- this.isExportDropdownOpen.update((v) => !v);
642
- this.isMetricDropdownOpen.set(false);
643
- }
644
- selectMetric(metric) {
645
- this.selectedMetricId.set(metric.id);
646
- this.isMetricDropdownOpen.set(false);
647
- this.metricChange.emit(metric);
648
- }
649
- onRefreshClick() {
650
- this.refresh.emit();
651
- }
652
- onCellMouseEnter(cell) {
653
- this.hoveredCell.set(cell);
654
- this.cellHover.emit(cell);
655
- }
656
- onCellMouseLeave() {
657
- this.hoveredCell.set(null);
658
- this.cellHover.emit(null);
659
- }
660
- onCellClick(cell, event) {
661
- this.cellClick.emit({
662
- cell,
663
- colKey: cell.colKey,
664
- rowKey: cell.rowKey,
665
- value: cell.value,
666
- interval: this.interval(),
667
- event
668
- });
669
- }
670
- onKeydown(event, colIdx, rowIdx) {
671
- const rows = this.gridRows();
672
- const cols = this.columnHeaders();
673
- let targetRow = rowIdx;
674
- let targetCol = colIdx;
675
- if (event.key === 'ArrowUp') {
676
- targetRow = Math.max(0, rowIdx - 1);
677
- event.preventDefault();
678
- }
679
- else if (event.key === 'ArrowDown') {
680
- targetRow = Math.min(rows.length - 1, rowIdx + 1);
681
- event.preventDefault();
682
- }
683
- else if (event.key === 'ArrowLeft') {
684
- targetCol = Math.max(0, colIdx - 1);
685
- event.preventDefault();
686
- }
687
- else if (event.key === 'ArrowRight') {
688
- targetCol = Math.min(cols.length - 1, colIdx + 1);
689
- event.preventDefault();
690
- }
691
- else if (event.key === 'Enter' || event.key === ' ') {
692
- const cell = rows[rowIdx]?.cells[colIdx];
693
- if (cell) {
694
- this.cellClick.emit({
695
- cell,
696
- colKey: cell.colKey,
697
- rowKey: cell.rowKey,
698
- value: cell.value,
699
- interval: this.interval(),
700
- event
701
- });
702
- }
703
- event.preventDefault();
704
- return;
705
- }
706
- if (targetRow !== rowIdx || targetCol !== colIdx) {
707
- this.focusedCoord.set({ colIndex: targetCol, rowIndex: targetRow });
708
- const cellEl = this.elementRef.nativeElement.querySelector(`[data-cell-coord="${targetRow}_${targetCol}"]`);
709
- cellEl?.focus();
710
- }
711
- }
712
- triggerExport(format) {
713
- this.isExportDropdownOpen.set(false);
714
- const rows = this.gridRows();
715
- const cols = this.days();
716
- if (format === 'csv') {
717
- const header = ['Period', ...cols].join(',');
718
- const body = rows.map((r) => [r.label, ...r.cells.map((c) => c.value)].join(',')).join('\n');
719
- const csvContent = `${header}\n${body}`;
720
- this.downloadFile(csvContent, 'text/csv;charset=utf-8;', `heatmap_${this.title().toLowerCase().replace(/\s+/g, '_')}.csv`);
721
- this.export.emit({ format: 'csv', data: csvContent });
722
- }
723
- else if (format === 'json') {
724
- const jsonRecords = {};
725
- rows.forEach((r) => {
726
- jsonRecords[r.label] = {};
727
- r.cells.forEach((c) => {
728
- jsonRecords[r.label][c.colKey] = c.value;
729
- });
730
- });
731
- const jsonStr = JSON.stringify(jsonRecords, null, 2);
732
- this.downloadFile(jsonStr, 'application/json;charset=utf-8;', `heatmap_${this.title().toLowerCase().replace(/\s+/g, '_')}.json`);
733
- this.export.emit({ format: 'json', data: jsonRecords });
734
- }
735
- }
736
- downloadFile(content, mimeType, filename) {
737
- if (typeof window === 'undefined')
738
- return;
739
- const blob = new Blob([content], { type: mimeType });
740
- const url = URL.createObjectURL(blob);
741
- const a = document.createElement('a');
742
- a.href = url;
743
- a.download = filename;
744
- document.body.appendChild(a);
745
- a.click();
746
- document.body.removeChild(a);
747
- URL.revokeObjectURL(url);
748
- }
749
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosHeatmapComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
750
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.1", type: TalosHeatmapComponent, isStandalone: true, selector: "talos-heatmap", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, metrics: { classPropertyName: "metrics", publicName: "metrics", isSignal: true, isRequired: false, transformFunction: null }, selectedMetricId: { classPropertyName: "selectedMetricId", publicName: "selectedMetricId", isSignal: true, isRequired: false, transformFunction: null }, interval: { classPropertyName: "interval", publicName: "interval", isSignal: true, isRequired: false, transformFunction: null }, dateRange: { classPropertyName: "dateRange", publicName: "dateRange", isSignal: true, isRequired: false, transformFunction: null }, swapAxes: { classPropertyName: "swapAxes", publicName: "swapAxes", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, hoursRange: { classPropertyName: "hoursRange", publicName: "hoursRange", isSignal: true, isRequired: false, transformFunction: null }, timeFormat: { classPropertyName: "timeFormat", publicName: "timeFormat", isSignal: true, isRequired: false, transformFunction: null }, days: { classPropertyName: "days", publicName: "days", isSignal: true, isRequired: false, transformFunction: null }, colorScheme: { classPropertyName: "colorScheme", publicName: "colorScheme", isSignal: true, isRequired: false, transformFunction: null }, customColorStops: { classPropertyName: "customColorStops", publicName: "customColorStops", isSignal: true, isRequired: false, transformFunction: null }, showLegend: { classPropertyName: "showLegend", publicName: "showLegend", isSignal: true, isRequired: false, transformFunction: null }, showValues: { classPropertyName: "showValues", publicName: "showValues", isSignal: true, isRequired: false, transformFunction: null }, cellShape: { classPropertyName: "cellShape", publicName: "cellShape", isSignal: true, isRequired: false, transformFunction: null }, cellSize: { classPropertyName: "cellSize", publicName: "cellSize", isSignal: true, isRequired: false, transformFunction: null }, fitWidth: { classPropertyName: "fitWidth", publicName: "fitWidth", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, showToolbar: { classPropertyName: "showToolbar", publicName: "showToolbar", isSignal: true, isRequired: false, transformFunction: null }, showRefresh: { classPropertyName: "showRefresh", publicName: "showRefresh", isSignal: true, isRequired: false, transformFunction: null }, showExport: { classPropertyName: "showExport", publicName: "showExport", isSignal: true, isRequired: false, transformFunction: null }, showExpand: { classPropertyName: "showExpand", publicName: "showExpand", isSignal: true, isRequired: false, transformFunction: null }, showSwapAxes: { classPropertyName: "showSwapAxes", publicName: "showSwapAxes", isSignal: true, isRequired: false, transformFunction: null }, showIntervalToggle: { classPropertyName: "showIntervalToggle", publicName: "showIntervalToggle", isSignal: true, isRequired: false, transformFunction: null }, showDateRangePicker: { classPropertyName: "showDateRangePicker", publicName: "showDateRangePicker", isSignal: true, isRequired: false, transformFunction: null }, dateRangePresets: { classPropertyName: "dateRangePresets", publicName: "dateRangePresets", isSignal: true, isRequired: false, transformFunction: null }, unit: { classPropertyName: "unit", publicName: "unit", isSignal: true, isRequired: false, transformFunction: null }, maxValue: { classPropertyName: "maxValue", publicName: "maxValue", isSignal: true, isRequired: false, transformFunction: null }, minValue: { classPropertyName: "minValue", publicName: "minValue", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedMetricId: "selectedMetricIdChange", interval: "intervalChange", dateRange: "dateRangeChange", swapAxes: "swapAxesChange", cellClick: "cellClick", cellHover: "cellHover", timeRangeChange: "timeRangeChange", refresh: "refresh", metricChange: "metricChange", export: "export" }, host: { properties: { "class.talos-heatmap-expanded": "isExpanded()", "class.talos-heatmap-loading": "loading()", "class.talos-heatmap-sm": "cellSize() === \"sm\"", "class.talos-heatmap-md": "cellSize() === \"md\"", "class.talos-heatmap-lg": "cellSize() === \"lg\"", "class.talos-heatmap-pill": "cellShape() === \"pill\"", "class.talos-heatmap-rounded": "cellShape() === \"rounded\"", "class.talos-heatmap-square": "cellShape() === \"square\"", "class.talos-heatmap-fit-width": "isFitWidth()", "class.talos-heatmap-compact-square": "!isFitWidth()", "class.talos-heatmap-swapped-axes": "swapAxes()", "attr.role": "\"region\"", "attr.aria-label": "title()" }, classAttribute: "talos-heatmap" }, ngImport: i0, template: "<div class=\"talos-heatmap-container\">\n <!-- Header Toolbar -->\n @if (showToolbar()) {\n <div class=\"talos-heatmap-header\">\n <div class=\"talos-heatmap-title-area\">\n <h3 class=\"talos-heatmap-title\">{{ title() }}</h3>\n </div>\n\n <div class=\"talos-heatmap-actions\">\n <!-- Interval Selector Toggle (Hour vs Day) -->\n @if (showIntervalToggle()) {\n <div class=\"talos-heatmap-interval-group\" role=\"radiogroup\" aria-label=\"Time Interval\">\n <button type=\"button\" class=\"talos-heatmap-interval-btn\" [class.is-active]=\"interval() === 'hour'\"\n (click)=\"setInterval('hour')\" role=\"radio\" [attr.aria-checked]=\"interval() === 'hour'\">\n <svg lucideClock [size]=\"13\"></svg>\n <span>Hour</span>\n </button>\n <button type=\"button\" class=\"talos-heatmap-interval-btn\" [class.is-active]=\"interval() === 'day'\"\n (click)=\"setInterval('day')\" role=\"radio\" [attr.aria-checked]=\"interval() === 'day'\">\n <svg lucideCalendar [size]=\"13\"></svg>\n <span>Day</span>\n </button>\n </div>\n }\n\n <!-- Date Range Picker Integration -->\n @if (showDateRangePicker()) {\n <div class=\"talos-heatmap-daterange-box\">\n <talos-date-range-picker size=\"sm\" [ngModel]=\"dateRange()\" (rangeChange)=\"onDateRangePickerChange($event)\"\n [presets]=\"dateRangePresets()\" placeholder=\"Select date range\" />\n </div>\n }\n\n <!-- Metric Dropdown Selector -->\n @if (metrics().length > 0) {\n <div class=\"talos-heatmap-dropdown-wrapper\">\n <button type=\"button\" class=\"talos-heatmap-dropdown-btn\" [class.is-open]=\"isMetricDropdownOpen()\"\n (click)=\"toggleMetricDropdown($event)\" aria-haspopup=\"listbox\" [attr.aria-expanded]=\"isMetricDropdownOpen()\">\n <span class=\"talos-heatmap-dropdown-label\">{{ currentMetric()?.label || 'Select metric' }}</span>\n <svg lucideChevronDown [size]=\"14\" class=\"talos-heatmap-dropdown-icon\"></svg>\n </button>\n\n @if (isMetricDropdownOpen()) {\n <div class=\"talos-heatmap-menu\" role=\"listbox\">\n @for (m of metrics(); track m.id) {\n <button type=\"button\" class=\"talos-heatmap-menu-item\" [class.is-selected]=\"m.id === currentMetric()?.id\"\n (click)=\"selectMetric(m)\" role=\"option\" [attr.aria-selected]=\"m.id === currentMetric()?.id\">\n <span>{{ m.label }}</span>\n @if (m.id === currentMetric()?.id) {\n <svg lucideCheck [size]=\"14\" class=\"talos-heatmap-check-icon\"></svg>\n }\n </button>\n }\n </div>\n }\n </div>\n }\n\n <!-- Refresh Button -->\n @if (showRefresh()) {\n <button type=\"button\" class=\"talos-heatmap-icon-btn\" [class.is-spinning]=\"loading()\" (click)=\"onRefreshClick()\"\n title=\"Refresh data\" aria-label=\"Refresh data\">\n <svg lucideRefreshCw [size]=\"16\" class=\"talos-heatmap-action-icon\"></svg>\n </button>\n }\n\n <!-- Export Dropdown Button -->\n @if (showExport()) {\n <div class=\"talos-heatmap-dropdown-wrapper\">\n <button type=\"button\" class=\"talos-heatmap-icon-btn\" (click)=\"toggleExportDropdown($event)\" title=\"Export data\"\n aria-label=\"Export data\">\n <svg lucideUpload [size]=\"16\" class=\"talos-heatmap-action-icon\"></svg>\n </button>\n\n @if (isExportDropdownOpen()) {\n <div class=\"talos-heatmap-menu talos-heatmap-export-menu\" role=\"menu\">\n <button type=\"button\" class=\"talos-heatmap-menu-item\" (click)=\"triggerExport('csv')\" role=\"menuitem\">\n <svg lucideFileSpreadsheet [size]=\"14\" class=\"talos-heatmap-menu-icon\"></svg>\n <span>Export to CSV</span>\n </button>\n <button type=\"button\" class=\"talos-heatmap-menu-item\" (click)=\"triggerExport('json')\" role=\"menuitem\">\n <svg lucideFileJson [size]=\"14\" class=\"talos-heatmap-menu-icon\"></svg>\n <span>Export to JSON</span>\n </button>\n </div>\n }\n </div>\n }\n\n <!-- Swap Axes Button -->\n @if (showSwapAxes()) {\n <button type=\"button\" class=\"talos-heatmap-icon-btn\" [class.is-active]=\"swapAxes()\" (click)=\"toggleSwapAxes()\"\n [title]=\"swapAxes() ? 'Reset axis orientation' : 'Swap axes (Days / Hours)'\"\n [attr.aria-label]=\"swapAxes() ? 'Reset axis orientation' : 'Swap axes (Days / Hours)'\">\n <svg lucideArrowLeftRight [size]=\"16\" class=\"talos-heatmap-action-icon\"></svg>\n </button>\n }\n\n <!-- Fullscreen / Expand Button -->\n @if (showExpand()) {\n <button type=\"button\" class=\"talos-heatmap-icon-btn\" (click)=\"toggleExpand()\"\n [title]=\"isExpanded() ? 'Minimize' : 'Expand'\" [aria-label]=\"isExpanded() ? 'Minimize' : 'Expand'\">\n @if (isExpanded()) {\n <svg lucideMinimize2 [size]=\"16\" class=\"talos-heatmap-action-icon\"></svg>\n } @else {\n <svg lucideMaximize2 [size]=\"16\" class=\"talos-heatmap-action-icon\"></svg>\n }\n </button>\n }\n </div>\n </div>\n }\n\n <!-- Heatmap Matrix Grid Wrapper -->\n <div class=\"talos-heatmap-body\" [class.is-loading]=\"loading()\">\n <!-- Grid Table -->\n <div class=\"talos-heatmap-grid\" role=\"grid\" [attr.aria-rowcount]=\"gridRows().length + 1\"\n [attr.aria-colcount]=\"columnHeaders().length + 1\">\n <!-- Column Headers -->\n <div class=\"talos-heatmap-row talos-heatmap-header-row\" role=\"row\" aria-rowindex=\"1\">\n <div class=\"talos-heatmap-corner-cell\" role=\"columnheader\"></div>\n @for (col of columnHeaders(); track col.key; let colIdx = $index) {\n <div class=\"talos-heatmap-col-header\" role=\"columnheader\" [attr.aria-colindex]=\"colIdx + 2\">\n {{ col.label }}\n </div>\n }\n </div>\n\n <!-- Data Rows -->\n @for (row of gridRows(); track row.key; let rowIdx = $index) {\n <div class=\"talos-heatmap-row\" role=\"row\" [attr.aria-rowindex]=\"rowIdx + 2\">\n <!-- Row Header (Hour or Week Range) -->\n <div class=\"talos-heatmap-row-header\" role=\"rowheader\" aria-colindex=\"1\" [title]=\"row.label\">\n {{ row.label }}\n </div>\n\n <!-- Heatmap Cells -->\n @for (cell of row.cells; track cell.id; let colIdx = $index) {\n <div class=\"talos-heatmap-cell-wrapper\" role=\"gridcell\" [attr.aria-colindex]=\"colIdx + 2\"\n [attr.aria-label]=\"cell.tooltipText\" tabindex=\"0\" [attr.data-cell-coord]=\"rowIdx + '_' + colIdx\"\n [talosTooltip]=\"cell.tooltipText\" (mouseenter)=\"onCellMouseEnter(cell)\" (mouseleave)=\"onCellMouseLeave()\"\n (click)=\"onCellClick(cell, $event)\" (keydown)=\"onKeydown($event, colIdx, rowIdx)\">\n <div class=\"talos-heatmap-pill\" [style.background-color]=\"cell.backgroundColor\" [style.color]=\"cell.textColor\"\n [class.has-value]=\"cell.value > 0\">\n @if (showValues()) {\n <span class=\"talos-heatmap-cell-value\">{{ cell.formattedValue }}</span>\n }\n </div>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Loading Skeleton Shimmer Overlay -->\n @if (loading()) {\n <div class=\"talos-heatmap-loading-overlay\" aria-hidden=\"true\">\n <div class=\"talos-heatmap-loading-spinner-box\">\n <svg lucideRefreshCw [size]=\"16\" class=\"talos-heatmap-loading-spinner\"></svg>\n <span>Loading data...</span>\n </div>\n </div>\n }\n </div>\n\n <!-- Bottom Legend Bar -->\n @if (showLegend()) {\n <div class=\"talos-heatmap-legend\">\n <span class=\"talos-heatmap-legend-bound\">{{ computedScaleBounds().min }}</span>\n <div class=\"talos-heatmap-legend-bar\" [style.background]=\"legendGradientCss()\" aria-hidden=\"true\"></div>\n <span class=\"talos-heatmap-legend-bound\">{{ computedScaleBounds().max }}</span>\n </div>\n }\n</div>", styles: [":host{display:block;font-family:inherit;--talos-heatmap-bg: var(--talos-card-bg, var(--talos-bg-surface, #ffffff));--talos-heatmap-text: var(--talos-text-color, #0f172a);--talos-heatmap-muted: var(--talos-text-muted, #64748b);--talos-heatmap-border: var(--talos-border-color, #e2e8f0);--talos-heatmap-hover-bg: var(--talos-primary-light, #f1f5f9);--talos-heatmap-cell-height: 28px;--talos-heatmap-cell-radius: 9999px;--talos-heatmap-row-header-width: 68px;--talos-heatmap-cell-font-size: .85rem;--talos-heatmap-gap: 6px;--talos-heatmap-square-size: 32px}:host(.talos-heatmap-sm){--talos-heatmap-cell-height: 22px;--talos-heatmap-row-header-width: 56px;--talos-heatmap-cell-font-size: .72rem;--talos-heatmap-square-size: 24px;--talos-heatmap-gap: 4px}:host(.talos-heatmap-md){--talos-heatmap-cell-height: 28px;--talos-heatmap-row-header-width: 68px;--talos-heatmap-cell-font-size: .82rem;--talos-heatmap-square-size: 32px;--talos-heatmap-gap: 6px}:host(.talos-heatmap-lg){--talos-heatmap-cell-height: 36px;--talos-heatmap-row-header-width: 80px;--talos-heatmap-cell-font-size: .92rem;--talos-heatmap-square-size: 40px;--talos-heatmap-gap: 8px}:host(.talos-heatmap-square){--talos-heatmap-cell-radius: 6px}:host(.talos-heatmap-rounded){--talos-heatmap-cell-radius: 8px}:host(.talos-heatmap-pill){--talos-heatmap-cell-radius: 9999px}:host(.talos-heatmap-expanded){position:fixed;inset:16px;z-index:1000;background:var(--talos-heatmap-bg);box-shadow:0 25px 50px -12px #00000059;border-radius:16px;padding:24px;overflow:auto;border:1px solid var(--talos-heatmap-border)}.talos-heatmap-container{display:flex;flex-direction:column;background:var(--talos-heatmap-bg);border-radius:12px;position:relative;width:100%}.talos-heatmap-header{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:20px;flex-wrap:wrap}.talos-heatmap-title{margin:0;font-size:1.15rem;font-weight:700;color:var(--talos-heatmap-text);letter-spacing:-.015em}.talos-heatmap-actions{display:flex;align-items:center;gap:8px;position:relative;flex-wrap:wrap}.talos-heatmap-interval-group{display:inline-flex;align-items:center;padding:2px;background:var(--talos-bg-color, #f1f5f9);border-radius:8px;border:1px solid var(--talos-heatmap-border);gap:2px}.talos-heatmap-interval-btn{display:inline-flex;align-items:center;gap:5px;padding:4px 10px;font-size:.78rem;font-weight:600;color:var(--talos-heatmap-muted);background:transparent;border:none;border-radius:6px;cursor:pointer;outline:none;transition:all .15s ease}.talos-heatmap-interval-btn:hover{color:var(--talos-heatmap-text)}.talos-heatmap-interval-btn.is-active{background:var(--talos-card-bg, #ffffff);color:var(--talos-primary-color, #4338ca);box-shadow:0 1px 3px #00000014}.talos-heatmap-daterange-box{min-width:220px}.talos-heatmap-dropdown-wrapper{position:relative}.talos-heatmap-dropdown-btn{display:inline-flex;align-items:center;gap:6px;padding:6px 12px;font-size:.85rem;font-weight:500;color:var(--talos-heatmap-text);background:var(--talos-bg-color, #f8fafc);border:1px solid var(--talos-heatmap-border);border-radius:8px;cursor:pointer;outline:none;transition:all .15s ease}.talos-heatmap-dropdown-btn:hover{background:var(--talos-primary-light, #f1f5f9);border-color:var(--talos-border-hover, #cbd5e1)}.talos-heatmap-dropdown-btn.is-open{background:var(--talos-primary-light-hover, #e2e8f0);border-color:var(--talos-border-hover, #94a3b8)}.talos-heatmap-dropdown-btn .talos-heatmap-dropdown-icon{width:14px;height:14px;color:var(--talos-heatmap-muted)}.talos-heatmap-icon-btn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:8px;border:1px solid transparent;background:transparent;color:var(--talos-heatmap-muted);cursor:pointer;outline:none;transition:all .15s ease}.talos-heatmap-icon-btn:hover{background:var(--talos-heatmap-hover-bg);color:var(--talos-heatmap-text)}.talos-heatmap-icon-btn.is-active{background:var(--talos-primary-light, #e0e7ff);color:var(--talos-primary-color, #4338ca);border-color:var(--talos-border-color, #c7d2fe)}.talos-heatmap-icon-btn:active{transform:scale(.95)}.talos-heatmap-icon-btn.is-spinning .talos-heatmap-action-icon{animation:talos-heatmap-spin .8s linear infinite}.talos-heatmap-icon-btn .talos-heatmap-action-icon{width:16px;height:16px}@keyframes talos-heatmap-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.talos-heatmap-menu{position:absolute;top:calc(100% + 4px);right:0;z-index:50;min-width:170px;background:var(--talos-dropdown-bg, var(--talos-card-bg, #ffffff));border:1px solid var(--talos-dropdown-border, var(--talos-heatmap-border));border-radius:10px;box-shadow:var(--talos-dropdown-shadow, 0 10px 25px -5px rgba(0, 0, 0, .12), 0 8px 10px -6px rgba(0, 0, 0, .08));padding:4px;display:flex;flex-direction:column;gap:2px;animation:talos-heatmap-menu-fade .15s cubic-bezier(.16,1,.3,1)}@keyframes talos-heatmap-menu-fade{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.talos-heatmap-menu-item{display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;padding:7px 10px;font-size:.82rem;font-weight:500;color:var(--talos-heatmap-text);background:transparent;border:none;border-radius:6px;text-align:left;cursor:pointer;transition:background .12s ease}.talos-heatmap-menu-item:hover{background:var(--talos-dropdown-hover-bg, #f1f5f9)}.talos-heatmap-menu-item.is-selected{font-weight:600;color:var(--talos-primary-color, #4338ca)}.talos-heatmap-menu-item .talos-heatmap-check-icon{width:14px;height:14px;color:var(--talos-primary-color, #4338ca)}.talos-heatmap-menu-item .talos-heatmap-menu-icon{width:14px;height:14px;color:var(--talos-heatmap-muted)}.talos-heatmap-body{position:relative;width:100%;overflow-x:auto;padding-bottom:8px}.talos-heatmap-body.is-loading{pointer-events:none;-webkit-user-select:none;user-select:none}.talos-heatmap-grid{display:flex;flex-direction:column;gap:var(--talos-heatmap-gap);width:100%}.talos-heatmap-row{display:flex;align-items:center;gap:var(--talos-heatmap-gap);width:100%}.talos-heatmap-header-row{margin-bottom:2px}.talos-heatmap-corner-cell{width:var(--talos-heatmap-row-header-width);flex-shrink:0}.talos-heatmap-row-header{width:var(--talos-heatmap-row-header-width);flex-shrink:0;text-align:right;padding-right:12px;font-size:.82rem;font-weight:500;color:var(--talos-heatmap-muted);-webkit-user-select:none;user-select:none;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}:host(.talos-heatmap-fit-width) .talos-heatmap-grid{min-width:440px;width:100%}:host(.talos-heatmap-fit-width) .talos-heatmap-col-header{flex:1;text-align:center;font-size:.82rem;font-weight:600;color:var(--talos-heatmap-muted);-webkit-user-select:none;user-select:none;letter-spacing:.01em}:host(.talos-heatmap-fit-width) .talos-heatmap-cell-wrapper{flex:1;height:var(--talos-heatmap-cell-height);position:relative;display:flex;align-items:center;justify-content:center;cursor:pointer;outline:none;border-radius:var(--talos-heatmap-cell-radius);transition:transform .15s ease}:host(.talos-heatmap-fit-width) .talos-heatmap-cell-wrapper:focus-visible{box-shadow:0 0 0 2px #4338ca,0 0 0 4px #4338ca40;z-index:5}:host(.talos-heatmap-compact-square) .talos-heatmap-grid{min-width:auto;width:max-content}:host(.talos-heatmap-compact-square) .talos-heatmap-col-header{width:var(--talos-heatmap-square-size);flex:0 0 var(--talos-heatmap-square-size);text-align:center;font-size:.78rem;font-weight:600;color:var(--talos-heatmap-muted);-webkit-user-select:none;user-select:none;letter-spacing:.01em}:host(.talos-heatmap-compact-square) .talos-heatmap-cell-wrapper{width:var(--talos-heatmap-square-size);height:var(--talos-heatmap-square-size);flex:0 0 var(--talos-heatmap-square-size);aspect-ratio:1/1;position:relative;display:flex;align-items:center;justify-content:center;cursor:pointer;outline:none;border-radius:var(--talos-heatmap-cell-radius);transition:transform .15s ease}:host(.talos-heatmap-compact-square) .talos-heatmap-cell-wrapper:focus-visible{box-shadow:0 0 0 2px #4338ca,0 0 0 4px #4338ca40;z-index:5}.talos-heatmap-pill{width:100%;height:100%;display:flex;align-items:center;justify-content:center;border-radius:var(--talos-heatmap-cell-radius);font-size:var(--talos-heatmap-cell-font-size);font-weight:600;line-height:1;-webkit-user-select:none;user-select:none;box-shadow:inset 0 0 0 1px #0000000a;transition:transform .15s cubic-bezier(.16,1,.3,1),box-shadow .15s ease,filter .15s ease}.talos-heatmap-pill:not(.has-value){box-shadow:inset 0 0 0 1px #e2e8f0e6}.talos-heatmap-cell-wrapper:hover .talos-heatmap-pill{transform:translateY(-2px) scale(1.05);box-shadow:0 6px 14px -2px #00000024,0 2px 4px -1px #0000000f;filter:brightness(1.03);z-index:2}.talos-heatmap-cell-wrapper:active .talos-heatmap-pill{transform:translateY(0) scale(.96)}.talos-heatmap-cell-value{display:inline-block;text-align:center}.talos-heatmap-loading-overlay{position:absolute;inset:0;background:var(--talos-loading-overlay-bg, rgba(255, 255, 255, .75));-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);display:flex;align-items:center;justify-content:center;z-index:40;border-radius:8px;animation:talos-heatmap-fade-in .2s ease}@keyframes talos-heatmap-fade-in{0%{opacity:0}to{opacity:1}}.talos-heatmap-loading-spinner-box{display:flex;align-items:center;gap:8px;padding:8px 16px;background:var(--talos-card-bg, #ffffff);border:1px solid var(--talos-heatmap-border);border-radius:8px;box-shadow:0 4px 12px #00000014;font-size:.85rem;font-weight:500;color:var(--talos-heatmap-text)}.talos-heatmap-loading-spinner-box .talos-heatmap-loading-spinner{width:16px;height:16px;color:var(--talos-primary-color, #4338ca);animation:talos-heatmap-spin .8s linear infinite}.talos-heatmap-legend{display:flex;align-items:center;gap:12px;margin-top:18px;padding-left:var(--talos-heatmap-row-header-width)}.talos-heatmap-legend-bound{font-size:.82rem;font-weight:600;color:var(--talos-heatmap-muted);min-width:12px}.talos-heatmap-legend-bar{height:8px;width:130px;border-radius:9999px;box-shadow:inset 0 1px 2px #00000014}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: DateRangePickerComponent, selector: "talos-date-range-picker", inputs: ["placeholder", "label", "floatingLabel", "floating", "required", "disabled", "clearable", "size", "displayFormat", "valueFormat", "showTime", "use24Hour", "showSeconds", "minuteStep", "minDate", "maxDate", "minSpan", "maxSpan", "firstDayOfWeek", "presets", "presetType", "filterDate"], outputs: ["rangeChange", "opened", "closed"] }, { kind: "directive", type: TalosTooltipDirective, selector: "[talosTooltip], [tooltip]", inputs: ["talosTooltip", "tooltip", "tooltipPosition", "tooltipDisabled"] }, { kind: "component", type: LucideRefreshCw, selector: "svg[lucideRefreshCw]" }, { kind: "component", type: LucideUpload, selector: "svg[lucideUpload]" }, { kind: "component", type: LucideMaximize2, selector: "svg[lucideMaximize2]" }, { kind: "component", type: LucideMinimize2, selector: "svg[lucideMinimize2]" }, { kind: "component", type: LucideChevronDown, selector: "svg[lucideChevronDown]" }, { kind: "component", type: LucideCheck, selector: "svg[lucideCheck]" }, { kind: "component", type: LucideFileSpreadsheet, selector: "svg[lucideFileSpreadsheet]" }, { kind: "component", type: LucideFileJson, selector: "svg[lucideFileBraces], svg[lucideFileJson]" }, { kind: "component", type: LucideCalendar, selector: "svg[lucideCalendar]" }, { kind: "component", type: LucideClock, selector: "svg[lucideClock]" }, { kind: "component", type: LucideArrowLeftRight, selector: "svg[lucideArrowLeftRight]" }] });
751
- }
752
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosHeatmapComponent, decorators: [{
753
- type: Component,
754
- args: [{ selector: 'talos-heatmap', imports: [
755
- FormsModule,
756
- DateRangePickerComponent,
757
- TalosTooltipDirective,
758
- LucideRefreshCw,
759
- LucideUpload,
760
- LucideMaximize2,
761
- LucideMinimize2,
762
- LucideChevronDown,
763
- LucideCheck,
764
- LucideFileSpreadsheet,
765
- LucideFileJson,
766
- LucideCalendar,
767
- LucideClock,
768
- LucideArrowLeftRight
769
- ], host: {
770
- 'class': 'talos-heatmap',
771
- '[class.talos-heatmap-expanded]': 'isExpanded()',
772
- '[class.talos-heatmap-loading]': 'loading()',
773
- '[class.talos-heatmap-sm]': 'cellSize() === "sm"',
774
- '[class.talos-heatmap-md]': 'cellSize() === "md"',
775
- '[class.talos-heatmap-lg]': 'cellSize() === "lg"',
776
- '[class.talos-heatmap-pill]': 'cellShape() === "pill"',
777
- '[class.talos-heatmap-rounded]': 'cellShape() === "rounded"',
778
- '[class.talos-heatmap-square]': 'cellShape() === "square"',
779
- '[class.talos-heatmap-fit-width]': 'isFitWidth()',
780
- '[class.talos-heatmap-compact-square]': '!isFitWidth()',
781
- '[class.talos-heatmap-swapped-axes]': 'swapAxes()',
782
- '[attr.role]': '"region"',
783
- '[attr.aria-label]': 'title()'
784
- }, template: "<div class=\"talos-heatmap-container\">\n <!-- Header Toolbar -->\n @if (showToolbar()) {\n <div class=\"talos-heatmap-header\">\n <div class=\"talos-heatmap-title-area\">\n <h3 class=\"talos-heatmap-title\">{{ title() }}</h3>\n </div>\n\n <div class=\"talos-heatmap-actions\">\n <!-- Interval Selector Toggle (Hour vs Day) -->\n @if (showIntervalToggle()) {\n <div class=\"talos-heatmap-interval-group\" role=\"radiogroup\" aria-label=\"Time Interval\">\n <button type=\"button\" class=\"talos-heatmap-interval-btn\" [class.is-active]=\"interval() === 'hour'\"\n (click)=\"setInterval('hour')\" role=\"radio\" [attr.aria-checked]=\"interval() === 'hour'\">\n <svg lucideClock [size]=\"13\"></svg>\n <span>Hour</span>\n </button>\n <button type=\"button\" class=\"talos-heatmap-interval-btn\" [class.is-active]=\"interval() === 'day'\"\n (click)=\"setInterval('day')\" role=\"radio\" [attr.aria-checked]=\"interval() === 'day'\">\n <svg lucideCalendar [size]=\"13\"></svg>\n <span>Day</span>\n </button>\n </div>\n }\n\n <!-- Date Range Picker Integration -->\n @if (showDateRangePicker()) {\n <div class=\"talos-heatmap-daterange-box\">\n <talos-date-range-picker size=\"sm\" [ngModel]=\"dateRange()\" (rangeChange)=\"onDateRangePickerChange($event)\"\n [presets]=\"dateRangePresets()\" placeholder=\"Select date range\" />\n </div>\n }\n\n <!-- Metric Dropdown Selector -->\n @if (metrics().length > 0) {\n <div class=\"talos-heatmap-dropdown-wrapper\">\n <button type=\"button\" class=\"talos-heatmap-dropdown-btn\" [class.is-open]=\"isMetricDropdownOpen()\"\n (click)=\"toggleMetricDropdown($event)\" aria-haspopup=\"listbox\" [attr.aria-expanded]=\"isMetricDropdownOpen()\">\n <span class=\"talos-heatmap-dropdown-label\">{{ currentMetric()?.label || 'Select metric' }}</span>\n <svg lucideChevronDown [size]=\"14\" class=\"talos-heatmap-dropdown-icon\"></svg>\n </button>\n\n @if (isMetricDropdownOpen()) {\n <div class=\"talos-heatmap-menu\" role=\"listbox\">\n @for (m of metrics(); track m.id) {\n <button type=\"button\" class=\"talos-heatmap-menu-item\" [class.is-selected]=\"m.id === currentMetric()?.id\"\n (click)=\"selectMetric(m)\" role=\"option\" [attr.aria-selected]=\"m.id === currentMetric()?.id\">\n <span>{{ m.label }}</span>\n @if (m.id === currentMetric()?.id) {\n <svg lucideCheck [size]=\"14\" class=\"talos-heatmap-check-icon\"></svg>\n }\n </button>\n }\n </div>\n }\n </div>\n }\n\n <!-- Refresh Button -->\n @if (showRefresh()) {\n <button type=\"button\" class=\"talos-heatmap-icon-btn\" [class.is-spinning]=\"loading()\" (click)=\"onRefreshClick()\"\n title=\"Refresh data\" aria-label=\"Refresh data\">\n <svg lucideRefreshCw [size]=\"16\" class=\"talos-heatmap-action-icon\"></svg>\n </button>\n }\n\n <!-- Export Dropdown Button -->\n @if (showExport()) {\n <div class=\"talos-heatmap-dropdown-wrapper\">\n <button type=\"button\" class=\"talos-heatmap-icon-btn\" (click)=\"toggleExportDropdown($event)\" title=\"Export data\"\n aria-label=\"Export data\">\n <svg lucideUpload [size]=\"16\" class=\"talos-heatmap-action-icon\"></svg>\n </button>\n\n @if (isExportDropdownOpen()) {\n <div class=\"talos-heatmap-menu talos-heatmap-export-menu\" role=\"menu\">\n <button type=\"button\" class=\"talos-heatmap-menu-item\" (click)=\"triggerExport('csv')\" role=\"menuitem\">\n <svg lucideFileSpreadsheet [size]=\"14\" class=\"talos-heatmap-menu-icon\"></svg>\n <span>Export to CSV</span>\n </button>\n <button type=\"button\" class=\"talos-heatmap-menu-item\" (click)=\"triggerExport('json')\" role=\"menuitem\">\n <svg lucideFileJson [size]=\"14\" class=\"talos-heatmap-menu-icon\"></svg>\n <span>Export to JSON</span>\n </button>\n </div>\n }\n </div>\n }\n\n <!-- Swap Axes Button -->\n @if (showSwapAxes()) {\n <button type=\"button\" class=\"talos-heatmap-icon-btn\" [class.is-active]=\"swapAxes()\" (click)=\"toggleSwapAxes()\"\n [title]=\"swapAxes() ? 'Reset axis orientation' : 'Swap axes (Days / Hours)'\"\n [attr.aria-label]=\"swapAxes() ? 'Reset axis orientation' : 'Swap axes (Days / Hours)'\">\n <svg lucideArrowLeftRight [size]=\"16\" class=\"talos-heatmap-action-icon\"></svg>\n </button>\n }\n\n <!-- Fullscreen / Expand Button -->\n @if (showExpand()) {\n <button type=\"button\" class=\"talos-heatmap-icon-btn\" (click)=\"toggleExpand()\"\n [title]=\"isExpanded() ? 'Minimize' : 'Expand'\" [aria-label]=\"isExpanded() ? 'Minimize' : 'Expand'\">\n @if (isExpanded()) {\n <svg lucideMinimize2 [size]=\"16\" class=\"talos-heatmap-action-icon\"></svg>\n } @else {\n <svg lucideMaximize2 [size]=\"16\" class=\"talos-heatmap-action-icon\"></svg>\n }\n </button>\n }\n </div>\n </div>\n }\n\n <!-- Heatmap Matrix Grid Wrapper -->\n <div class=\"talos-heatmap-body\" [class.is-loading]=\"loading()\">\n <!-- Grid Table -->\n <div class=\"talos-heatmap-grid\" role=\"grid\" [attr.aria-rowcount]=\"gridRows().length + 1\"\n [attr.aria-colcount]=\"columnHeaders().length + 1\">\n <!-- Column Headers -->\n <div class=\"talos-heatmap-row talos-heatmap-header-row\" role=\"row\" aria-rowindex=\"1\">\n <div class=\"talos-heatmap-corner-cell\" role=\"columnheader\"></div>\n @for (col of columnHeaders(); track col.key; let colIdx = $index) {\n <div class=\"talos-heatmap-col-header\" role=\"columnheader\" [attr.aria-colindex]=\"colIdx + 2\">\n {{ col.label }}\n </div>\n }\n </div>\n\n <!-- Data Rows -->\n @for (row of gridRows(); track row.key; let rowIdx = $index) {\n <div class=\"talos-heatmap-row\" role=\"row\" [attr.aria-rowindex]=\"rowIdx + 2\">\n <!-- Row Header (Hour or Week Range) -->\n <div class=\"talos-heatmap-row-header\" role=\"rowheader\" aria-colindex=\"1\" [title]=\"row.label\">\n {{ row.label }}\n </div>\n\n <!-- Heatmap Cells -->\n @for (cell of row.cells; track cell.id; let colIdx = $index) {\n <div class=\"talos-heatmap-cell-wrapper\" role=\"gridcell\" [attr.aria-colindex]=\"colIdx + 2\"\n [attr.aria-label]=\"cell.tooltipText\" tabindex=\"0\" [attr.data-cell-coord]=\"rowIdx + '_' + colIdx\"\n [talosTooltip]=\"cell.tooltipText\" (mouseenter)=\"onCellMouseEnter(cell)\" (mouseleave)=\"onCellMouseLeave()\"\n (click)=\"onCellClick(cell, $event)\" (keydown)=\"onKeydown($event, colIdx, rowIdx)\">\n <div class=\"talos-heatmap-pill\" [style.background-color]=\"cell.backgroundColor\" [style.color]=\"cell.textColor\"\n [class.has-value]=\"cell.value > 0\">\n @if (showValues()) {\n <span class=\"talos-heatmap-cell-value\">{{ cell.formattedValue }}</span>\n }\n </div>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Loading Skeleton Shimmer Overlay -->\n @if (loading()) {\n <div class=\"talos-heatmap-loading-overlay\" aria-hidden=\"true\">\n <div class=\"talos-heatmap-loading-spinner-box\">\n <svg lucideRefreshCw [size]=\"16\" class=\"talos-heatmap-loading-spinner\"></svg>\n <span>Loading data...</span>\n </div>\n </div>\n }\n </div>\n\n <!-- Bottom Legend Bar -->\n @if (showLegend()) {\n <div class=\"talos-heatmap-legend\">\n <span class=\"talos-heatmap-legend-bound\">{{ computedScaleBounds().min }}</span>\n <div class=\"talos-heatmap-legend-bar\" [style.background]=\"legendGradientCss()\" aria-hidden=\"true\"></div>\n <span class=\"talos-heatmap-legend-bound\">{{ computedScaleBounds().max }}</span>\n </div>\n }\n</div>", styles: [":host{display:block;font-family:inherit;--talos-heatmap-bg: var(--talos-card-bg, var(--talos-bg-surface, #ffffff));--talos-heatmap-text: var(--talos-text-color, #0f172a);--talos-heatmap-muted: var(--talos-text-muted, #64748b);--talos-heatmap-border: var(--talos-border-color, #e2e8f0);--talos-heatmap-hover-bg: var(--talos-primary-light, #f1f5f9);--talos-heatmap-cell-height: 28px;--talos-heatmap-cell-radius: 9999px;--talos-heatmap-row-header-width: 68px;--talos-heatmap-cell-font-size: .85rem;--talos-heatmap-gap: 6px;--talos-heatmap-square-size: 32px}:host(.talos-heatmap-sm){--talos-heatmap-cell-height: 22px;--talos-heatmap-row-header-width: 56px;--talos-heatmap-cell-font-size: .72rem;--talos-heatmap-square-size: 24px;--talos-heatmap-gap: 4px}:host(.talos-heatmap-md){--talos-heatmap-cell-height: 28px;--talos-heatmap-row-header-width: 68px;--talos-heatmap-cell-font-size: .82rem;--talos-heatmap-square-size: 32px;--talos-heatmap-gap: 6px}:host(.talos-heatmap-lg){--talos-heatmap-cell-height: 36px;--talos-heatmap-row-header-width: 80px;--talos-heatmap-cell-font-size: .92rem;--talos-heatmap-square-size: 40px;--talos-heatmap-gap: 8px}:host(.talos-heatmap-square){--talos-heatmap-cell-radius: 6px}:host(.talos-heatmap-rounded){--talos-heatmap-cell-radius: 8px}:host(.talos-heatmap-pill){--talos-heatmap-cell-radius: 9999px}:host(.talos-heatmap-expanded){position:fixed;inset:16px;z-index:1000;background:var(--talos-heatmap-bg);box-shadow:0 25px 50px -12px #00000059;border-radius:16px;padding:24px;overflow:auto;border:1px solid var(--talos-heatmap-border)}.talos-heatmap-container{display:flex;flex-direction:column;background:var(--talos-heatmap-bg);border-radius:12px;position:relative;width:100%}.talos-heatmap-header{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:20px;flex-wrap:wrap}.talos-heatmap-title{margin:0;font-size:1.15rem;font-weight:700;color:var(--talos-heatmap-text);letter-spacing:-.015em}.talos-heatmap-actions{display:flex;align-items:center;gap:8px;position:relative;flex-wrap:wrap}.talos-heatmap-interval-group{display:inline-flex;align-items:center;padding:2px;background:var(--talos-bg-color, #f1f5f9);border-radius:8px;border:1px solid var(--talos-heatmap-border);gap:2px}.talos-heatmap-interval-btn{display:inline-flex;align-items:center;gap:5px;padding:4px 10px;font-size:.78rem;font-weight:600;color:var(--talos-heatmap-muted);background:transparent;border:none;border-radius:6px;cursor:pointer;outline:none;transition:all .15s ease}.talos-heatmap-interval-btn:hover{color:var(--talos-heatmap-text)}.talos-heatmap-interval-btn.is-active{background:var(--talos-card-bg, #ffffff);color:var(--talos-primary-color, #4338ca);box-shadow:0 1px 3px #00000014}.talos-heatmap-daterange-box{min-width:220px}.talos-heatmap-dropdown-wrapper{position:relative}.talos-heatmap-dropdown-btn{display:inline-flex;align-items:center;gap:6px;padding:6px 12px;font-size:.85rem;font-weight:500;color:var(--talos-heatmap-text);background:var(--talos-bg-color, #f8fafc);border:1px solid var(--talos-heatmap-border);border-radius:8px;cursor:pointer;outline:none;transition:all .15s ease}.talos-heatmap-dropdown-btn:hover{background:var(--talos-primary-light, #f1f5f9);border-color:var(--talos-border-hover, #cbd5e1)}.talos-heatmap-dropdown-btn.is-open{background:var(--talos-primary-light-hover, #e2e8f0);border-color:var(--talos-border-hover, #94a3b8)}.talos-heatmap-dropdown-btn .talos-heatmap-dropdown-icon{width:14px;height:14px;color:var(--talos-heatmap-muted)}.talos-heatmap-icon-btn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:8px;border:1px solid transparent;background:transparent;color:var(--talos-heatmap-muted);cursor:pointer;outline:none;transition:all .15s ease}.talos-heatmap-icon-btn:hover{background:var(--talos-heatmap-hover-bg);color:var(--talos-heatmap-text)}.talos-heatmap-icon-btn.is-active{background:var(--talos-primary-light, #e0e7ff);color:var(--talos-primary-color, #4338ca);border-color:var(--talos-border-color, #c7d2fe)}.talos-heatmap-icon-btn:active{transform:scale(.95)}.talos-heatmap-icon-btn.is-spinning .talos-heatmap-action-icon{animation:talos-heatmap-spin .8s linear infinite}.talos-heatmap-icon-btn .talos-heatmap-action-icon{width:16px;height:16px}@keyframes talos-heatmap-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.talos-heatmap-menu{position:absolute;top:calc(100% + 4px);right:0;z-index:50;min-width:170px;background:var(--talos-dropdown-bg, var(--talos-card-bg, #ffffff));border:1px solid var(--talos-dropdown-border, var(--talos-heatmap-border));border-radius:10px;box-shadow:var(--talos-dropdown-shadow, 0 10px 25px -5px rgba(0, 0, 0, .12), 0 8px 10px -6px rgba(0, 0, 0, .08));padding:4px;display:flex;flex-direction:column;gap:2px;animation:talos-heatmap-menu-fade .15s cubic-bezier(.16,1,.3,1)}@keyframes talos-heatmap-menu-fade{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.talos-heatmap-menu-item{display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;padding:7px 10px;font-size:.82rem;font-weight:500;color:var(--talos-heatmap-text);background:transparent;border:none;border-radius:6px;text-align:left;cursor:pointer;transition:background .12s ease}.talos-heatmap-menu-item:hover{background:var(--talos-dropdown-hover-bg, #f1f5f9)}.talos-heatmap-menu-item.is-selected{font-weight:600;color:var(--talos-primary-color, #4338ca)}.talos-heatmap-menu-item .talos-heatmap-check-icon{width:14px;height:14px;color:var(--talos-primary-color, #4338ca)}.talos-heatmap-menu-item .talos-heatmap-menu-icon{width:14px;height:14px;color:var(--talos-heatmap-muted)}.talos-heatmap-body{position:relative;width:100%;overflow-x:auto;padding-bottom:8px}.talos-heatmap-body.is-loading{pointer-events:none;-webkit-user-select:none;user-select:none}.talos-heatmap-grid{display:flex;flex-direction:column;gap:var(--talos-heatmap-gap);width:100%}.talos-heatmap-row{display:flex;align-items:center;gap:var(--talos-heatmap-gap);width:100%}.talos-heatmap-header-row{margin-bottom:2px}.talos-heatmap-corner-cell{width:var(--talos-heatmap-row-header-width);flex-shrink:0}.talos-heatmap-row-header{width:var(--talos-heatmap-row-header-width);flex-shrink:0;text-align:right;padding-right:12px;font-size:.82rem;font-weight:500;color:var(--talos-heatmap-muted);-webkit-user-select:none;user-select:none;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}:host(.talos-heatmap-fit-width) .talos-heatmap-grid{min-width:440px;width:100%}:host(.talos-heatmap-fit-width) .talos-heatmap-col-header{flex:1;text-align:center;font-size:.82rem;font-weight:600;color:var(--talos-heatmap-muted);-webkit-user-select:none;user-select:none;letter-spacing:.01em}:host(.talos-heatmap-fit-width) .talos-heatmap-cell-wrapper{flex:1;height:var(--talos-heatmap-cell-height);position:relative;display:flex;align-items:center;justify-content:center;cursor:pointer;outline:none;border-radius:var(--talos-heatmap-cell-radius);transition:transform .15s ease}:host(.talos-heatmap-fit-width) .talos-heatmap-cell-wrapper:focus-visible{box-shadow:0 0 0 2px #4338ca,0 0 0 4px #4338ca40;z-index:5}:host(.talos-heatmap-compact-square) .talos-heatmap-grid{min-width:auto;width:max-content}:host(.talos-heatmap-compact-square) .talos-heatmap-col-header{width:var(--talos-heatmap-square-size);flex:0 0 var(--talos-heatmap-square-size);text-align:center;font-size:.78rem;font-weight:600;color:var(--talos-heatmap-muted);-webkit-user-select:none;user-select:none;letter-spacing:.01em}:host(.talos-heatmap-compact-square) .talos-heatmap-cell-wrapper{width:var(--talos-heatmap-square-size);height:var(--talos-heatmap-square-size);flex:0 0 var(--talos-heatmap-square-size);aspect-ratio:1/1;position:relative;display:flex;align-items:center;justify-content:center;cursor:pointer;outline:none;border-radius:var(--talos-heatmap-cell-radius);transition:transform .15s ease}:host(.talos-heatmap-compact-square) .talos-heatmap-cell-wrapper:focus-visible{box-shadow:0 0 0 2px #4338ca,0 0 0 4px #4338ca40;z-index:5}.talos-heatmap-pill{width:100%;height:100%;display:flex;align-items:center;justify-content:center;border-radius:var(--talos-heatmap-cell-radius);font-size:var(--talos-heatmap-cell-font-size);font-weight:600;line-height:1;-webkit-user-select:none;user-select:none;box-shadow:inset 0 0 0 1px #0000000a;transition:transform .15s cubic-bezier(.16,1,.3,1),box-shadow .15s ease,filter .15s ease}.talos-heatmap-pill:not(.has-value){box-shadow:inset 0 0 0 1px #e2e8f0e6}.talos-heatmap-cell-wrapper:hover .talos-heatmap-pill{transform:translateY(-2px) scale(1.05);box-shadow:0 6px 14px -2px #00000024,0 2px 4px -1px #0000000f;filter:brightness(1.03);z-index:2}.talos-heatmap-cell-wrapper:active .talos-heatmap-pill{transform:translateY(0) scale(.96)}.talos-heatmap-cell-value{display:inline-block;text-align:center}.talos-heatmap-loading-overlay{position:absolute;inset:0;background:var(--talos-loading-overlay-bg, rgba(255, 255, 255, .75));-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);display:flex;align-items:center;justify-content:center;z-index:40;border-radius:8px;animation:talos-heatmap-fade-in .2s ease}@keyframes talos-heatmap-fade-in{0%{opacity:0}to{opacity:1}}.talos-heatmap-loading-spinner-box{display:flex;align-items:center;gap:8px;padding:8px 16px;background:var(--talos-card-bg, #ffffff);border:1px solid var(--talos-heatmap-border);border-radius:8px;box-shadow:0 4px 12px #00000014;font-size:.85rem;font-weight:500;color:var(--talos-heatmap-text)}.talos-heatmap-loading-spinner-box .talos-heatmap-loading-spinner{width:16px;height:16px;color:var(--talos-primary-color, #4338ca);animation:talos-heatmap-spin .8s linear infinite}.talos-heatmap-legend{display:flex;align-items:center;gap:12px;margin-top:18px;padding-left:var(--talos-heatmap-row-header-width)}.talos-heatmap-legend-bound{font-size:.82rem;font-weight:600;color:var(--talos-heatmap-muted);min-width:12px}.talos-heatmap-legend-bar{height:8px;width:130px;border-radius:9999px;box-shadow:inset 0 1px 2px #00000014}\n"] }]
785
- }], ctorParameters: () => [], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], metrics: [{ type: i0.Input, args: [{ isSignal: true, alias: "metrics", required: false }] }], selectedMetricId: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedMetricId", required: false }] }, { type: i0.Output, args: ["selectedMetricIdChange"] }], interval: [{ type: i0.Input, args: [{ isSignal: true, alias: "interval", required: false }] }, { type: i0.Output, args: ["intervalChange"] }], dateRange: [{ type: i0.Input, args: [{ isSignal: true, alias: "dateRange", required: false }] }, { type: i0.Output, args: ["dateRangeChange"] }], swapAxes: [{ type: i0.Input, args: [{ isSignal: true, alias: "swapAxes", required: false }] }, { type: i0.Output, args: ["swapAxesChange"] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], hoursRange: [{ type: i0.Input, args: [{ isSignal: true, alias: "hoursRange", required: false }] }], timeFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeFormat", required: false }] }], days: [{ type: i0.Input, args: [{ isSignal: true, alias: "days", required: false }] }], colorScheme: [{ type: i0.Input, args: [{ isSignal: true, alias: "colorScheme", required: false }] }], customColorStops: [{ type: i0.Input, args: [{ isSignal: true, alias: "customColorStops", required: false }] }], showLegend: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLegend", required: false }] }], showValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "showValues", required: false }] }], cellShape: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellShape", required: false }] }], cellSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellSize", required: false }] }], fitWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fitWidth", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], showToolbar: [{ type: i0.Input, args: [{ isSignal: true, alias: "showToolbar", required: false }] }], showRefresh: [{ type: i0.Input, args: [{ isSignal: true, alias: "showRefresh", required: false }] }], showExport: [{ type: i0.Input, args: [{ isSignal: true, alias: "showExport", required: false }] }], showExpand: [{ type: i0.Input, args: [{ isSignal: true, alias: "showExpand", required: false }] }], showSwapAxes: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSwapAxes", required: false }] }], showIntervalToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "showIntervalToggle", required: false }] }], showDateRangePicker: [{ type: i0.Input, args: [{ isSignal: true, alias: "showDateRangePicker", required: false }] }], dateRangePresets: [{ type: i0.Input, args: [{ isSignal: true, alias: "dateRangePresets", required: false }] }], unit: [{ type: i0.Input, args: [{ isSignal: true, alias: "unit", required: false }] }], maxValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxValue", required: false }] }], minValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "minValue", required: false }] }], cellClick: [{ type: i0.Output, args: ["cellClick"] }], cellHover: [{ type: i0.Output, args: ["cellHover"] }], timeRangeChange: [{ type: i0.Output, args: ["timeRangeChange"] }], refresh: [{ type: i0.Output, args: ["refresh"] }], metricChange: [{ type: i0.Output, args: ["metricChange"] }], export: [{ type: i0.Output, args: ["export"] }] } });
786
-
787
- class TalosHeatmapModule {
788
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosHeatmapModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
789
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.1.1", ngImport: i0, type: TalosHeatmapModule, imports: [TalosHeatmapComponent], exports: [TalosHeatmapComponent] });
790
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosHeatmapModule, imports: [TalosHeatmapComponent] });
791
- }
792
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.1", ngImport: i0, type: TalosHeatmapModule, decorators: [{
793
- type: NgModule,
794
- args: [{
795
- imports: [TalosHeatmapComponent],
796
- exports: [TalosHeatmapComponent]
797
- }]
798
- }] });
799
-
800
- /**
801
- * Generated bundle index. Do not edit.
802
- */
803
-
804
- export { TalosHeatmapComponent, TalosHeatmapModule };
805
- //# sourceMappingURL=weeehaoooz-talos-ui-data-viz-heatmap.mjs.map