@k2b/ui 0.50.0 → 0.51.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 (294) hide show
  1. package/dist/base.css +32 -1
  2. package/dist/browser/actions/Button.js.map +1 -1
  3. package/dist/browser/actions/CommandList.js +861 -0
  4. package/dist/browser/actions/CommandList.js.map +1 -0
  5. package/dist/browser/actions/CommandMenu.js +237 -0
  6. package/dist/browser/actions/CommandMenu.js.map +1 -0
  7. package/dist/browser/actions/Dropdown.js +43 -10
  8. package/dist/browser/actions/Dropdown.js.map +1 -1
  9. package/dist/browser/actions/command-dock.js +47 -0
  10. package/dist/browser/actions/command-dock.js.map +1 -0
  11. package/dist/browser/actions/command-items.js +84 -0
  12. package/dist/browser/actions/command-items.js.map +1 -0
  13. package/dist/browser/actions/command-messages.js +42 -0
  14. package/dist/browser/actions/command-messages.js.map +1 -0
  15. package/dist/browser/actions/index.js +1 -0
  16. package/dist/browser/actions/index.js.map +1 -1
  17. package/dist/browser/charts/core/area.js +3 -5
  18. package/dist/browser/charts/core/area.js.map +1 -1
  19. package/dist/browser/charts/core/calendar.js +1 -1
  20. package/dist/browser/charts/core/calendar.js.map +1 -1
  21. package/dist/browser/charts/core/chart-messages.js +17 -0
  22. package/dist/browser/charts/core/chart-messages.js.map +1 -0
  23. package/dist/browser/charts/core/hbar-layout.js +118 -0
  24. package/dist/browser/charts/core/hbar-layout.js.map +1 -0
  25. package/dist/browser/charts/core/hbar.js +39 -0
  26. package/dist/browser/charts/core/hbar.js.map +1 -0
  27. package/dist/browser/charts/core/index.js +7 -2
  28. package/dist/browser/charts/core/index.js.map +1 -1
  29. package/dist/browser/charts/core/map.js +116 -0
  30. package/dist/browser/charts/core/map.js.map +1 -0
  31. package/dist/browser/charts/core/registry.js +22 -15
  32. package/dist/browser/charts/core/registry.js.map +1 -1
  33. package/dist/browser/charts/core/render-size.js +13 -0
  34. package/dist/browser/charts/core/render-size.js.map +1 -0
  35. package/dist/browser/charts/core/render.js +20 -10
  36. package/dist/browser/charts/core/render.js.map +1 -1
  37. package/dist/browser/charts/core/snapshot.js +3 -3
  38. package/dist/browser/charts/core/snapshot.js.map +1 -1
  39. package/dist/browser/charts/core/svg-renderers.js +2406 -0
  40. package/dist/browser/charts/core/svg-renderers.js.map +1 -0
  41. package/dist/browser/charts/core/svg.js +4 -2525
  42. package/dist/browser/charts/core/svg.js.map +1 -1
  43. package/dist/browser/charts/core/types.js +0 -2
  44. package/dist/browser/charts/core/types.js.map +1 -1
  45. package/dist/browser/charts/core/waterfall.js +162 -0
  46. package/dist/browser/charts/core/waterfall.js.map +1 -0
  47. package/dist/browser/charts/description.js +2 -0
  48. package/dist/browser/charts/description.js.map +1 -0
  49. package/dist/browser/charts.js.map +1 -1
  50. package/dist/browser/content/Chart.js +14 -628
  51. package/dist/browser/content/Chart.js.map +1 -1
  52. package/dist/browser/content/ChartRoot.js +632 -0
  53. package/dist/browser/content/ChartRoot.js.map +1 -0
  54. package/dist/browser/content/ChartSparkline.js +24 -0
  55. package/dist/browser/content/ChartSparkline.js.map +1 -0
  56. package/dist/browser/content/FileView.js +111 -61
  57. package/dist/browser/content/FileView.js.map +1 -1
  58. package/dist/browser/content/Lightbox.js +8 -8
  59. package/dist/browser/content/Lightbox.js.map +1 -1
  60. package/dist/browser/content/MapView.js +30 -28
  61. package/dist/browser/content/MapView.js.map +1 -1
  62. package/dist/browser/content/PdfPreview.js +84 -52
  63. package/dist/browser/content/PdfPreview.js.map +1 -1
  64. package/dist/browser/content/PdfViewer.js +588 -0
  65. package/dist/browser/content/PdfViewer.js.map +1 -0
  66. package/dist/browser/content/chart-bar.js +246 -16
  67. package/dist/browser/content/chart-bar.js.map +1 -1
  68. package/dist/browser/content/chart-inspection-core.js +22 -21
  69. package/dist/browser/content/chart-inspection-core.js.map +1 -1
  70. package/dist/browser/content/chart-line-gaps.js +1 -1
  71. package/dist/browser/content/chart-line-gaps.js.map +1 -1
  72. package/dist/browser/content/chart-message-catalog.js +10 -0
  73. package/dist/browser/content/chart-message-catalog.js.map +1 -1
  74. package/dist/browser/content/chart-state-timeline.js +1 -1
  75. package/dist/browser/content/chart-state-timeline.js.map +1 -1
  76. package/dist/browser/content/chart-svg.js +2 -1
  77. package/dist/browser/content/chart-svg.js.map +1 -1
  78. package/dist/browser/content/index.js +1 -0
  79. package/dist/browser/content/index.js.map +1 -1
  80. package/dist/browser/content/pdf-document.js +29 -0
  81. package/dist/browser/content/pdf-document.js.map +1 -0
  82. package/dist/browser/content/pdf-limits.js +31 -0
  83. package/dist/browser/content/pdf-limits.js.map +1 -0
  84. package/dist/browser/content/pdf-messages.js +34 -2
  85. package/dist/browser/content/pdf-messages.js.map +1 -1
  86. package/dist/browser/content/pdf-viewer-engine.js +57 -0
  87. package/dist/browser/content/pdf-viewer-worker.js +28 -0
  88. package/dist/browser/inputs/ChoiceInputs.js +94 -51
  89. package/dist/browser/inputs/ChoiceInputs.js.map +1 -1
  90. package/dist/browser/inputs/ChoiceSlider.js +75 -58
  91. package/dist/browser/inputs/ChoiceSlider.js.map +1 -1
  92. package/dist/browser/inputs/DatePicker.js +113 -98
  93. package/dist/browser/inputs/DatePicker.js.map +1 -1
  94. package/dist/browser/inputs/PeriodPicker.js +874 -0
  95. package/dist/browser/inputs/PeriodPicker.js.map +1 -0
  96. package/dist/browser/inputs/index.js +4 -1
  97. package/dist/browser/inputs/index.js.map +1 -1
  98. package/dist/browser/inputs/input-messages.js +8 -2
  99. package/dist/browser/inputs/input-messages.js.map +1 -1
  100. package/dist/browser/inputs/markdown/MarkdownEditor.js +14 -10
  101. package/dist/browser/inputs/markdown/MarkdownEditor.js.map +1 -1
  102. package/dist/browser/inputs/markdown/SlashCommands.js +402 -0
  103. package/dist/browser/inputs/markdown/SlashCommands.js.map +1 -0
  104. package/dist/browser/inputs/period-picker-messages.js +71 -0
  105. package/dist/browser/inputs/period-picker-messages.js.map +1 -0
  106. package/dist/browser/inputs/period.js +263 -0
  107. package/dist/browser/inputs/period.js.map +1 -0
  108. package/dist/browser/layout/DetailPanel.js +147 -120
  109. package/dist/browser/layout/DetailPanel.js.map +1 -1
  110. package/dist/browser/layout/Discussion.js +101 -108
  111. package/dist/browser/layout/Discussion.js.map +1 -1
  112. package/dist/browser/layout/index.js.map +1 -1
  113. package/dist/browser/surfaces/DescriptionList.js +5 -2
  114. package/dist/browser/surfaces/DescriptionList.js.map +1 -1
  115. package/dist/browser/surfaces/StatCell.js +19 -14
  116. package/dist/browser/surfaces/StatCell.js.map +1 -1
  117. package/dist/browser/surfaces/delta-badge.js +16 -2
  118. package/dist/browser/surfaces/delta-badge.js.map +1 -1
  119. package/dist/browser/widgets/DashboardFrame.js +310 -0
  120. package/dist/browser/widgets/DashboardFrame.js.map +1 -0
  121. package/dist/browser/widgets/index.js +1 -0
  122. package/dist/browser/widgets/index.js.map +1 -1
  123. package/dist/licenses/pdfjs-dist.txt +177 -0
  124. package/dist/ssr/actions/Button.js.map +1 -1
  125. package/dist/ssr/actions/CommandList.js +638 -0
  126. package/dist/ssr/actions/CommandList.js.map +1 -0
  127. package/dist/ssr/actions/CommandMenu.js +197 -0
  128. package/dist/ssr/actions/CommandMenu.js.map +1 -0
  129. package/dist/ssr/actions/Dropdown.js +43 -10
  130. package/dist/ssr/actions/Dropdown.js.map +1 -1
  131. package/dist/ssr/actions/command-dock.js +47 -0
  132. package/dist/ssr/actions/command-dock.js.map +1 -0
  133. package/dist/ssr/actions/command-items.js +84 -0
  134. package/dist/ssr/actions/command-items.js.map +1 -0
  135. package/dist/ssr/actions/command-messages.js +42 -0
  136. package/dist/ssr/actions/command-messages.js.map +1 -0
  137. package/dist/ssr/actions/index.js +1 -0
  138. package/dist/ssr/actions/index.js.map +1 -1
  139. package/dist/ssr/charts/core/area.js +3 -5
  140. package/dist/ssr/charts/core/area.js.map +1 -1
  141. package/dist/ssr/charts/core/calendar.js +1 -1
  142. package/dist/ssr/charts/core/calendar.js.map +1 -1
  143. package/dist/ssr/charts/core/chart-messages.js +17 -0
  144. package/dist/ssr/charts/core/chart-messages.js.map +1 -0
  145. package/dist/ssr/charts/core/hbar-layout.js +118 -0
  146. package/dist/ssr/charts/core/hbar-layout.js.map +1 -0
  147. package/dist/ssr/charts/core/hbar.js +39 -0
  148. package/dist/ssr/charts/core/hbar.js.map +1 -0
  149. package/dist/ssr/charts/core/index.js +7 -2
  150. package/dist/ssr/charts/core/index.js.map +1 -1
  151. package/dist/ssr/charts/core/map.js +116 -0
  152. package/dist/ssr/charts/core/map.js.map +1 -0
  153. package/dist/ssr/charts/core/registry.js +22 -15
  154. package/dist/ssr/charts/core/registry.js.map +1 -1
  155. package/dist/ssr/charts/core/render-size.js +13 -0
  156. package/dist/ssr/charts/core/render-size.js.map +1 -0
  157. package/dist/ssr/charts/core/render.js +20 -10
  158. package/dist/ssr/charts/core/render.js.map +1 -1
  159. package/dist/ssr/charts/core/snapshot.js +3 -3
  160. package/dist/ssr/charts/core/snapshot.js.map +1 -1
  161. package/dist/ssr/charts/core/svg-renderers.js +2406 -0
  162. package/dist/ssr/charts/core/svg-renderers.js.map +1 -0
  163. package/dist/ssr/charts/core/svg.js +4 -2525
  164. package/dist/ssr/charts/core/svg.js.map +1 -1
  165. package/dist/ssr/charts/core/types.js +0 -2
  166. package/dist/ssr/charts/core/types.js.map +1 -1
  167. package/dist/ssr/charts/core/waterfall.js +162 -0
  168. package/dist/ssr/charts/core/waterfall.js.map +1 -0
  169. package/dist/ssr/charts/description.js +2 -0
  170. package/dist/ssr/charts/description.js.map +1 -0
  171. package/dist/ssr/charts.js.map +1 -1
  172. package/dist/ssr/content/Chart.js +14 -471
  173. package/dist/ssr/content/Chart.js.map +1 -1
  174. package/dist/ssr/content/ChartRoot.js +475 -0
  175. package/dist/ssr/content/ChartRoot.js.map +1 -0
  176. package/dist/ssr/content/ChartSparkline.js +24 -0
  177. package/dist/ssr/content/ChartSparkline.js.map +1 -0
  178. package/dist/ssr/content/FileView.js +56 -7
  179. package/dist/ssr/content/FileView.js.map +1 -1
  180. package/dist/ssr/content/Lightbox.js +8 -8
  181. package/dist/ssr/content/Lightbox.js.map +1 -1
  182. package/dist/ssr/content/MapView.js +9 -9
  183. package/dist/ssr/content/MapView.js.map +1 -1
  184. package/dist/ssr/content/PdfPreview.js +49 -20
  185. package/dist/ssr/content/PdfPreview.js.map +1 -1
  186. package/dist/ssr/content/PdfViewer.js +484 -0
  187. package/dist/ssr/content/PdfViewer.js.map +1 -0
  188. package/dist/ssr/content/chart-bar.js +246 -16
  189. package/dist/ssr/content/chart-bar.js.map +1 -1
  190. package/dist/ssr/content/chart-inspection-core.js +22 -21
  191. package/dist/ssr/content/chart-inspection-core.js.map +1 -1
  192. package/dist/ssr/content/chart-line-gaps.js +1 -1
  193. package/dist/ssr/content/chart-line-gaps.js.map +1 -1
  194. package/dist/ssr/content/chart-message-catalog.js +10 -0
  195. package/dist/ssr/content/chart-message-catalog.js.map +1 -1
  196. package/dist/ssr/content/chart-state-timeline.js +1 -1
  197. package/dist/ssr/content/chart-state-timeline.js.map +1 -1
  198. package/dist/ssr/content/chart-svg.js +2 -1
  199. package/dist/ssr/content/chart-svg.js.map +1 -1
  200. package/dist/ssr/content/index.js +1 -0
  201. package/dist/ssr/content/index.js.map +1 -1
  202. package/dist/ssr/content/pdf-document.js +29 -0
  203. package/dist/ssr/content/pdf-document.js.map +1 -0
  204. package/dist/ssr/content/pdf-limits.js +31 -0
  205. package/dist/ssr/content/pdf-limits.js.map +1 -0
  206. package/dist/ssr/content/pdf-messages.js +34 -2
  207. package/dist/ssr/content/pdf-messages.js.map +1 -1
  208. package/dist/ssr/inputs/ChoiceInputs.js +49 -12
  209. package/dist/ssr/inputs/ChoiceInputs.js.map +1 -1
  210. package/dist/ssr/inputs/ChoiceSlider.js +17 -12
  211. package/dist/ssr/inputs/ChoiceSlider.js.map +1 -1
  212. package/dist/ssr/inputs/DatePicker.js +14 -9
  213. package/dist/ssr/inputs/DatePicker.js.map +1 -1
  214. package/dist/ssr/inputs/PeriodPicker.js +598 -0
  215. package/dist/ssr/inputs/PeriodPicker.js.map +1 -0
  216. package/dist/ssr/inputs/index.js +4 -1
  217. package/dist/ssr/inputs/index.js.map +1 -1
  218. package/dist/ssr/inputs/input-messages.js +8 -2
  219. package/dist/ssr/inputs/input-messages.js.map +1 -1
  220. package/dist/ssr/inputs/markdown/MarkdownEditor.js +3 -2
  221. package/dist/ssr/inputs/markdown/MarkdownEditor.js.map +1 -1
  222. package/dist/ssr/inputs/markdown/SlashCommands.js +339 -0
  223. package/dist/ssr/inputs/markdown/SlashCommands.js.map +1 -0
  224. package/dist/ssr/inputs/period-picker-messages.js +71 -0
  225. package/dist/ssr/inputs/period-picker-messages.js.map +1 -0
  226. package/dist/ssr/inputs/period.js +263 -0
  227. package/dist/ssr/inputs/period.js.map +1 -0
  228. package/dist/ssr/layout/DetailPanel.js +27 -4
  229. package/dist/ssr/layout/DetailPanel.js.map +1 -1
  230. package/dist/ssr/layout/Discussion.js +16 -2
  231. package/dist/ssr/layout/Discussion.js.map +1 -1
  232. package/dist/ssr/layout/index.js.map +1 -1
  233. package/dist/ssr/surfaces/DescriptionList.js +1 -1
  234. package/dist/ssr/surfaces/DescriptionList.js.map +1 -1
  235. package/dist/ssr/surfaces/StatCell.js +4 -5
  236. package/dist/ssr/surfaces/StatCell.js.map +1 -1
  237. package/dist/ssr/surfaces/delta-badge.js +16 -2
  238. package/dist/ssr/surfaces/delta-badge.js.map +1 -1
  239. package/dist/ssr/widgets/DashboardFrame.js +200 -0
  240. package/dist/ssr/widgets/DashboardFrame.js.map +1 -0
  241. package/dist/ssr/widgets/index.js +1 -0
  242. package/dist/ssr/widgets/index.js.map +1 -1
  243. package/dist/styles.css +1 -1
  244. package/dist/types/actions/Button.d.ts +1 -1
  245. package/dist/types/actions/CommandList.d.ts +120 -0
  246. package/dist/types/actions/CommandMenu.d.ts +39 -0
  247. package/dist/types/actions/Dropdown.d.ts +17 -0
  248. package/dist/types/actions/command-dock.d.ts +8 -0
  249. package/dist/types/actions/command-items.d.ts +134 -0
  250. package/dist/types/actions/command-messages.d.ts +19 -0
  251. package/dist/types/actions/index.d.ts +3 -0
  252. package/dist/types/charts/core/calendar.d.ts +1 -1
  253. package/dist/types/charts/core/chart-messages.d.ts +5 -0
  254. package/dist/types/charts/core/hbar-layout.d.ts +74 -0
  255. package/dist/types/charts/core/hbar.d.ts +13 -0
  256. package/dist/types/charts/core/index.d.ts +7 -2
  257. package/dist/types/charts/core/map.d.ts +3 -0
  258. package/dist/types/charts/core/registry.d.ts +17 -11
  259. package/dist/types/charts/core/render-size.d.ts +7 -0
  260. package/dist/types/charts/core/render.d.ts +1 -4
  261. package/dist/types/charts/core/snapshot.d.ts +2 -2
  262. package/dist/types/charts/core/svg-renderers.d.ts +722 -0
  263. package/dist/types/charts/core/svg.d.ts +4 -698
  264. package/dist/types/charts/core/types.d.ts +1 -12
  265. package/dist/types/charts/core/waterfall.d.ts +68 -0
  266. package/dist/types/charts/description.d.ts +226 -0
  267. package/dist/types/charts.d.ts +1 -0
  268. package/dist/types/content/Chart.d.ts +3 -91
  269. package/dist/types/content/ChartRoot.d.ts +92 -0
  270. package/dist/types/content/ChartSparkline.d.ts +5 -0
  271. package/dist/types/content/PdfViewer.d.ts +32 -0
  272. package/dist/types/content/chart-bar.d.ts +95 -2
  273. package/dist/types/content/index.d.ts +2 -0
  274. package/dist/types/content/pdf-document.d.ts +5 -0
  275. package/dist/types/content/pdf-engine.d.ts +9 -0
  276. package/dist/types/content/pdf-limits.d.ts +43 -0
  277. package/dist/types/content/pdf-messages.d.ts +16 -0
  278. package/dist/types/inputs/ChoiceInputs.d.ts +4 -0
  279. package/dist/types/inputs/ChoiceSlider.d.ts +12 -0
  280. package/dist/types/inputs/DatePicker.d.ts +22 -0
  281. package/dist/types/inputs/PeriodPicker.d.ts +24 -0
  282. package/dist/types/inputs/index.d.ts +8 -2
  283. package/dist/types/inputs/input-messages.d.ts +3 -0
  284. package/dist/types/inputs/markdown/MarkdownEditor.d.ts +5 -0
  285. package/dist/types/inputs/markdown/SlashCommands.d.ts +20 -0
  286. package/dist/types/inputs/period-picker-messages.d.ts +34 -0
  287. package/dist/types/inputs/period.d.ts +134 -0
  288. package/dist/types/layout/DetailPanel.d.ts +12 -0
  289. package/dist/types/layout/index.d.ts +1 -1
  290. package/dist/types/surfaces/DescriptionList.d.ts +5 -0
  291. package/dist/types/surfaces/StatCell.d.ts +6 -1
  292. package/dist/types/widgets/DashboardFrame.d.ts +58 -0
  293. package/dist/types/widgets/index.d.ts +1 -0
  294. package/package.json +2 -1
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["surfaces/StatCell.tsx"],"sourcesContent":["import { type JSX, Match, Show, Switch } from \"solid-js\";\nimport Chart from \"../content/Chart\";\nimport type { ChartTooltipFormatter } from \"../content/chart-inspection-core\";\nimport { useLocale } from \"../intl/locale\";\nimport type { AccentColor } from \"../semantics\";\nimport { DeltaBadge } from \"./delta-badge\";\nimport { type StatGridSize, useStatGridSize, useStatGridSurface } from \"./StatGrid\";\nimport { useStatCellMessages } from \"./stat-cell-messages\";\n\nexport type StatCellTone = AccentColor;\n\nexport type StatCellAccent = {\n tone: StatCellTone;\n icon: string;\n text?: string;\n};\n\n/**\n * The change against a comparison period. `unit: \"ratio\"` (default) reads `0.082` as `+8.2 %`; `\"points\"` is the\n * difference of two shares in ratio units, so `0.031` reads `+3.1 pts`. Only with `better` does the badge carry a tone\n * and say \"better\" or \"worse\"; without it the change stays unrated.\n */\nexport type StatCellDelta = {\n value: number;\n unit?: \"ratio\" | \"points\";\n better?: \"up\" | \"down\";\n};\n\n/** The value the change compares against, shown under the figure, such as \"Last month 44,560\". */\nexport type StatCellCompare = {\n label: string;\n value: string | number;\n};\n\nexport type StatCellSize = StatGridSize;\n\nexport type StatCellProps = {\n label: string;\n /** The figure. `null` shows the empty dash; `sub` then says why. */\n value: string | number | JSX.Element | null;\n sub?: string;\n valueClass?: string;\n /** An icon in a chip before the label, in `tone`. `\"in\"` and `\"out\"` are the money colours of `FlowAmount`. */\n icon?: string;\n /** The chip colour of `icon`. Defaults to zinc. */\n tone?: StatCellTone | \"in\" | \"out\";\n accent?: StatCellAccent;\n delta?: StatCellDelta;\n compare?: StatCellCompare;\n href?: string;\n title?: string;\n trend?: readonly number[];\n /**\n * Replaces the default trend tooltip in browser code, for example with a period title or a unit.\n * `selection.datum.index` is the source index into `trend`.\n */\n trendTooltip?: ChartTooltipFormatter;\n size?: StatCellSize;\n /**\n * Wraps the label, value and support line instead of truncating them. Use it for a cell whose height nothing\n * reserves, such as one figure on its own; cells compared in a row keep one line each.\n */\n wrap?: boolean;\n /** `\"loading\"` keeps the tile's size with placeholders; `\"error\"` says the figure did not load. */\n status?: \"loading\" | \"error\";\n /** Offers \"Try again\" after an error and \"Reload\" beside `stale`. */\n onRetry?: () => void;\n /** The figure is not current: a short note such as \"As of 09:12 · not current\" replaces the support line. */\n stale?: string;\n};\n\nfunction Body(props: StatCellProps): JSX.Element {\n const gridSize = useStatGridSize();\n const size = () => props.size ?? gridSize;\n const accent = () => props.accent;\n const locale = useLocale();\n const t = useStatCellMessages();\n const defaultTrendTooltip: ChartTooltipFormatter = ({ datum }) => {\n const y = datum.values.find((field) => field.key === \"y\")?.value ?? \"\";\n return {\n rows: [\n { label: props.label, value: typeof y === \"number\" ? new Intl.NumberFormat(locale(), { maximumFractionDigits: 6 }).format(y) : y },\n ],\n };\n };\n const compareValue = () => {\n const value = props.compare?.value;\n return typeof value === \"number\" ? new Intl.NumberFormat(locale()).format(value) : value;\n };\n const empty = () => props.value === null || props.value === undefined || props.value === \"\";\n return (\n <>\n <div class=\"k2b-stat-cell__head\">\n <Show when={props.icon}>\n {(icon) => (\n <span class=\"k2b-stat-cell__icon k2b-icon-tile\" data-tone={props.tone ?? \"zinc\"} aria-hidden=\"true\">\n <i class={icon()} />\n </span>\n )}\n </Show>\n <span class=\"k2b-stat-cell__label\" data-size={size()}>\n {props.label}\n </span>\n </div>\n <div class=\"k2b-stat-cell__main\">\n <Switch\n fallback={\n <>\n <span\n class={`k2b-stat-cell__value ${props.valueClass ?? \"\"}`}\n data-size={size()}\n data-empty={empty() || undefined}\n title={props.title}\n >\n {empty() ? \"–\" : props.value}\n </span>\n <Show when={!empty() && props.delta}>{(delta) => <DeltaBadge delta={delta()} compare={props.compare} />}</Show>\n </>\n }\n >\n <Match when={props.status === \"loading\"}>\n <span class=\"k2b-stat-cell__skeleton k2b-skeleton\" data-part=\"value\" aria-hidden=\"true\" />\n <span class=\"k2b-sr-only\">{t().loading}</span>\n </Match>\n <Match when={props.status === \"error\"}>\n <span class=\"k2b-stat-cell__error\">\n <i class=\"ti ti-alert-circle\" aria-hidden=\"true\" />\n {t().notLoaded}\n </span>\n </Match>\n </Switch>\n </div>\n <div class=\"k2b-stat-cell__support\">\n <Switch\n fallback={\n <Show\n when={props.stale}\n fallback={\n <>\n <Show when={props.compare}>\n {(compare) => (\n <span class=\"k2b-stat-cell__sub\">\n {compare().label} {compareValue()}\n </span>\n )}\n </Show>\n <Show when={props.sub}>{(sub) => <span class=\"k2b-stat-cell__sub\">{sub()}</span>}</Show>\n <Show when={accent()}>\n {(value) => (\n <Show\n when={value().text}\n fallback={<i class={`${value().icon} k2b-stat-cell__accent-icon`} data-tone={value().tone} aria-hidden=\"true\" />}\n >\n {(text) => (\n <span class=\"k2b-stat-cell__accent\" data-tone={value().tone}>\n <i class={value().icon} aria-hidden=\"true\" />\n {text()}\n </span>\n )}\n </Show>\n )}\n </Show>\n {/* No figure, no trend: an empty tile says why in `sub` and keeps the size of its other states. */}\n <Show when={!empty() && props.trend && props.trend.length > 1}>\n <Chart\n kind=\"sparkline\"\n labels={{ interactiveChart: props.label }}\n tooltip={props.trendTooltip ?? defaultTrendTooltip}\n class=\"k2b-stat-cell__trend\"\n data={Array.from(props.trend ?? [])}\n showLast\n />\n </Show>\n </>\n }\n >\n {(stale) => (\n <>\n <span class=\"k2b-stat-cell__stale\">\n <i class=\"ti ti-clock-exclamation\" aria-hidden=\"true\" />\n {stale()}\n </span>\n <Show when={props.onRetry}>\n {(retry) => (\n <button type=\"button\" class=\"k2b-stat-cell__retry\" onClick={() => retry()()}>\n {t().reload}\n </button>\n )}\n </Show>\n </>\n )}\n </Show>\n }\n >\n <Match when={props.status === \"loading\"}>\n <span class=\"k2b-stat-cell__skeleton k2b-skeleton\" data-part=\"support\" aria-hidden=\"true\" />\n </Match>\n <Match when={props.status === \"error\"}>\n <Show when={props.onRetry}>\n {(retry) => (\n <button type=\"button\" class=\"k2b-stat-cell__retry\" onClick={() => retry()()}>\n {t().retry}\n </button>\n )}\n </Show>\n </Match>\n </Switch>\n </div>\n </>\n );\n}\n\n/**\n * One key figure as a framed tile: icon and label, the figure with its change, and a support line with the comparison\n * and the trend. Each state (loading, error, stale, empty) keeps the tile's place and size.\n */\nexport function StatCell(props: StatCellProps): JSX.Element {\n const gridSize = useStatGridSize();\n const size = () => props.size ?? gridSize;\n const surface = useStatGridSurface();\n return (\n <Show\n // A tile that offers a retry is no link: the button must not sit inside it.\n when={props.href && !props.status && !(props.stale && props.onRetry)}\n fallback={\n <div\n class=\"k2b-stat-cell\"\n data-size={size()}\n data-surface={surface}\n data-wrap={props.wrap || undefined}\n data-status={props.status}\n aria-busy={props.status === \"loading\" || undefined}\n >\n <Body {...props} />\n </div>\n }\n >\n <a\n href={props.href}\n class=\"k2b-stat-cell k2b-stat-cell--link\"\n data-size={size()}\n data-surface={surface}\n data-wrap={props.wrap || undefined}\n >\n <i class=\"ti ti-external-link k2b-stat-cell__link-icon\" aria-hidden=\"true\" />\n <Body {...props} />\n </a>\n </Show>\n );\n}\n\nexport default StatCell;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["surfaces/StatCell.tsx"],"sourcesContent":["import { type JSX, Match, Show, Switch } from \"solid-js\";\nimport type { ChartNumberFormat } from \"../charts/description\";\nimport { ChartSparkline } from \"../content/ChartSparkline\";\nimport type { ChartTooltipFormatter } from \"../content/chart-inspection-core\";\nimport { useLocale } from \"../intl/locale\";\nimport type { AccentColor } from \"../semantics\";\nimport { DeltaBadge } from \"./delta-badge\";\nimport { type StatGridSize, useStatGridSize, useStatGridSurface } from \"./StatGrid\";\nimport { useStatCellMessages } from \"./stat-cell-messages\";\n\nexport type StatCellTone = AccentColor;\n\nexport type StatCellAccent = {\n tone: StatCellTone;\n icon: string;\n text?: string;\n};\n\n/**\n * The change against a comparison period. `unit: \"ratio\"` (default) reads `0.082` as `+8.2 %`; `\"points\"` is the\n * difference of two shares in ratio units, so `0.031` reads `+3.1 pts`. Only with `better` does the badge carry a tone\n * and say \"better\" or \"worse\"; without it the change stays unrated.\n */\nexport type StatCellDelta = {\n value: number;\n unit?: \"ratio\" | \"points\" | \"absolute\";\n /** Existing measures can express a change in their own unit instead of a ratio. */\n format?: ChartNumberFormat;\n better?: \"up\" | \"down\";\n};\n\n/** The value the change compares against, shown under the figure, such as \"Last month 44,560\". */\nexport type StatCellCompare = {\n label: string;\n value: string | number;\n};\n\nexport type StatCellSize = StatGridSize;\n\nexport type StatCellProps = {\n label: string;\n /** The figure. `null` shows the empty dash; `sub` then says why. */\n value: string | number | JSX.Element | null;\n sub?: string;\n valueClass?: string;\n /** An icon in a chip before the label, in `tone`. `\"in\"` and `\"out\"` are the money colours of `FlowAmount`. */\n icon?: string;\n /** The chip colour of `icon`. Defaults to zinc. */\n tone?: StatCellTone | \"in\" | \"out\";\n accent?: StatCellAccent;\n delta?: StatCellDelta;\n /** Keep the figure and change on separate rows, including while loading. Defaults to beside the figure. */\n deltaPlacement?: \"below\";\n compare?: StatCellCompare;\n href?: string;\n title?: string;\n trend?: readonly number[];\n /**\n * Replaces the default trend tooltip in browser code, for example with a period title or a unit.\n * `selection.datum.index` is the source index into `trend`.\n */\n trendTooltip?: ChartTooltipFormatter;\n size?: StatCellSize;\n /**\n * Wraps the label, value and support line instead of truncating them. Use it for a cell whose height nothing\n * reserves, such as one figure on its own; cells compared in a row keep one line each.\n */\n wrap?: boolean;\n /** `\"loading\"` keeps the tile's size with placeholders; `\"error\"` says the figure did not load. */\n status?: \"loading\" | \"error\";\n /** Offers \"Try again\" after an error and \"Reload\" beside `stale`. */\n onRetry?: () => void;\n /** The figure is not current: a short note such as \"As of 09:12 · not current\" replaces the support line. */\n stale?: string;\n};\n\nfunction Body(props: StatCellProps): JSX.Element {\n const gridSize = useStatGridSize();\n const size = () => props.size ?? gridSize;\n const accent = () => props.accent;\n const locale = useLocale();\n const t = useStatCellMessages();\n const defaultTrendTooltip: ChartTooltipFormatter = ({ datum }) => {\n const y = datum.values.find((field) => field.key === \"y\")?.value ?? \"\";\n return {\n rows: [\n { label: props.label, value: typeof y === \"number\" ? new Intl.NumberFormat(locale(), { maximumFractionDigits: 6 }).format(y) : y },\n ],\n };\n };\n const compareValue = () => {\n const value = props.compare?.value;\n return typeof value === \"number\" ? new Intl.NumberFormat(locale()).format(value) : value;\n };\n const empty = () => props.value === null || props.value === undefined || props.value === \"\";\n return (\n <>\n <div class=\"k2b-stat-cell__head\">\n <Show when={props.icon}>\n {(icon) => (\n <span class=\"k2b-stat-cell__icon k2b-icon-tile\" data-tone={props.tone ?? \"zinc\"} aria-hidden=\"true\">\n <i class={icon()} />\n </span>\n )}\n </Show>\n <span class=\"k2b-stat-cell__label\" data-size={size()}>\n {props.label}\n </span>\n </div>\n <div class=\"k2b-stat-cell__main\">\n <Switch\n fallback={\n <>\n <span\n class={`k2b-stat-cell__value ${props.valueClass ?? \"\"}`}\n data-size={size()}\n data-empty={empty() || undefined}\n title={props.title}\n >\n {empty() ? \"–\" : props.value}\n </span>\n <Show when={!empty() && props.delta}>{(delta) => <DeltaBadge delta={delta()} compare={props.compare} />}</Show>\n </>\n }\n >\n <Match when={props.status === \"loading\"}>\n <span class=\"k2b-stat-cell__skeleton k2b-skeleton\" data-part=\"value\" aria-hidden=\"true\" />\n <span class=\"k2b-sr-only\">{t().loading}</span>\n </Match>\n <Match when={props.status === \"error\"}>\n <span class=\"k2b-stat-cell__error\">\n <i class=\"ti ti-alert-circle\" aria-hidden=\"true\" />\n {t().notLoaded}\n </span>\n </Match>\n </Switch>\n </div>\n <div class=\"k2b-stat-cell__support\">\n <Switch\n fallback={\n <Show\n when={props.stale}\n fallback={\n <>\n <Show when={props.compare}>\n {(compare) => (\n <span class=\"k2b-stat-cell__sub\">\n {compare().label} {compareValue()}\n </span>\n )}\n </Show>\n <Show when={props.sub}>{(sub) => <span class=\"k2b-stat-cell__sub\">{sub()}</span>}</Show>\n <Show when={accent()}>\n {(value) => (\n <Show\n when={value().text}\n fallback={<i class={`${value().icon} k2b-stat-cell__accent-icon`} data-tone={value().tone} aria-hidden=\"true\" />}\n >\n {(text) => (\n <span class=\"k2b-stat-cell__accent\" data-tone={value().tone}>\n <i class={value().icon} aria-hidden=\"true\" />\n {text()}\n </span>\n )}\n </Show>\n )}\n </Show>\n {/* No figure, no trend: an empty tile says why in `sub` and keeps the size of its other states. */}\n <Show when={!empty() && props.trend && props.trend.length > 1}>\n <ChartSparkline\n labels={{ interactiveChart: props.label }}\n tooltip={props.trendTooltip ?? defaultTrendTooltip}\n class=\"k2b-stat-cell__trend\"\n data={Array.from(props.trend ?? [])}\n showLast\n />\n </Show>\n </>\n }\n >\n {(stale) => (\n <>\n <span class=\"k2b-stat-cell__stale\">\n <i class=\"ti ti-clock-exclamation\" aria-hidden=\"true\" />\n {stale()}\n </span>\n <Show when={props.onRetry}>\n {(retry) => (\n <button type=\"button\" class=\"k2b-stat-cell__retry\" onClick={() => retry()()}>\n {t().reload}\n </button>\n )}\n </Show>\n </>\n )}\n </Show>\n }\n >\n <Match when={props.status === \"loading\"}>\n <span class=\"k2b-stat-cell__skeleton k2b-skeleton\" data-part=\"support\" aria-hidden=\"true\" />\n </Match>\n <Match when={props.status === \"error\"}>\n <Show when={props.onRetry}>\n {(retry) => (\n <button type=\"button\" class=\"k2b-stat-cell__retry\" onClick={() => retry()()}>\n {t().retry}\n </button>\n )}\n </Show>\n </Match>\n </Switch>\n </div>\n </>\n );\n}\n\n/**\n * One key figure as a framed tile: icon and label, the figure with its change, and a support line with the comparison\n * and the trend. Each state (loading, error, stale, empty) keeps the tile's place and size.\n */\nexport function StatCell(props: StatCellProps): JSX.Element {\n const gridSize = useStatGridSize();\n const size = () => props.size ?? gridSize;\n const surface = useStatGridSurface();\n return (\n <Show\n // A tile that offers a retry is no link: the button must not sit inside it.\n when={props.href && !props.status && !(props.stale && props.onRetry)}\n fallback={\n <div\n class=\"k2b-stat-cell\"\n data-size={size()}\n data-surface={surface}\n data-wrap={props.wrap || undefined}\n data-delta-placement={props.deltaPlacement}\n data-status={props.status}\n aria-busy={props.status === \"loading\" || undefined}\n >\n <Body {...props} />\n </div>\n }\n >\n <a\n href={props.href}\n class=\"k2b-stat-cell k2b-stat-cell--link\"\n data-size={size()}\n data-surface={surface}\n data-wrap={props.wrap || undefined}\n data-delta-placement={props.deltaPlacement}\n >\n <i class=\"ti ti-external-link k2b-stat-cell__link-icon\" aria-hidden=\"true\" />\n <Body {...props} />\n </a>\n </Show>\n );\n}\n\nexport default StatCell;\n"],"mappings":"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","ignoreList":[]}
@@ -12,14 +12,28 @@ import { useStatCellMessages } from "./stat-cell-messages";
12
12
  // The change badge of a key figure, on its own so a table cell can show it without the tile and its trend chart.
13
13
 
14
14
  /** The change as shown: one decimal of a percent or point, so text, arrow and rating never disagree. */
15
- const shownDelta = delta => Math.round(delta.value * 1000) / 1000 || 0;
15
+ const shownDelta = delta => delta.unit === "absolute" ? delta.value || 0 : Math.round(delta.value * 1000) / 1000 || 0;
16
16
  const deltaTone = delta => {
17
17
  const value = shownDelta(delta);
18
18
  return !delta.better || value === 0 ? "neutral" : value > 0 === (delta.better === "up") ? "good" : "bad";
19
19
  };
20
20
 
21
21
  /** Signed with a true minus sign (U+2212), as figures are typeset. */
22
- export const deltaText = (delta, locale, t) => (delta.unit === "points" ? `${new Intl.NumberFormat(locale, {
22
+ export const deltaText = (delta, locale, t) => (delta.unit === "absolute" ? `${new Intl.NumberFormat(locale, {
23
+ ...(!delta.format ? {
24
+ maximumSignificantDigits: 15
25
+ } : {}),
26
+ style: delta.format?.style === "number" ? "decimal" : delta.format?.style,
27
+ currency: delta.format?.currency,
28
+ ...(delta.format?.decimals === undefined ? {} : {
29
+ minimumFractionDigits: delta.format.decimals,
30
+ maximumFractionDigits: delta.format.decimals
31
+ }),
32
+ ...(delta.format?.compact ? {
33
+ notation: "compact"
34
+ } : {}),
35
+ signDisplay: "exceptZero"
36
+ }).format(delta.value === 0 ? 0 : delta.value)}${delta.format?.unit ? ` ${delta.format.unit}` : ""}` : delta.unit === "points" ? `${new Intl.NumberFormat(locale, {
23
37
  minimumFractionDigits: 1,
24
38
  maximumFractionDigits: 1,
25
39
  signDisplay: "exceptZero"
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["surfaces/delta-badge.tsx"],"sourcesContent":["import type { JSX } from \"solid-js\";\nimport { useLocale } from \"../intl/locale\";\nimport type { StatCellCompare, StatCellDelta } from \"./StatCell\";\nimport { type StatCellMessages, useStatCellMessages } from \"./stat-cell-messages\";\n\n// The change badge of a key figure, on its own so a table cell can show it without the tile and its trend chart.\n\n/** The change as shown: one decimal of a percent or point, so text, arrow and rating never disagree. */\nconst shownDelta = (delta: StatCellDelta): number => Math.round(delta.value * 1000) / 1000 || 0;\n\nconst deltaTone = (delta: StatCellDelta): \"good\" | \"bad\" | \"neutral\" => {\n const value = shownDelta(delta);\n return !delta.better || value === 0 ? \"neutral\" : value > 0 === (delta.better === \"up\") ? \"good\" : \"bad\";\n};\n\n/** Signed with a true minus sign (U+2212), as figures are typeset. */\nexport const deltaText = (delta: StatCellDelta, locale: string, t: StatCellMessages): string =>\n (delta.unit === \"points\"\n ? `${new Intl.NumberFormat(locale, { minimumFractionDigits: 1, maximumFractionDigits: 1, signDisplay: \"exceptZero\" }).format(shownDelta(delta) * 100)} ${t.points}`\n : new Intl.NumberFormat(locale, {\n style: \"percent\",\n minimumFractionDigits: 1,\n maximumFractionDigits: 1,\n signDisplay: \"exceptZero\",\n }).format(shownDelta(delta))\n ).replace(\"-\", \"\\u2212\");\n\n/** A change badge: arrow, signed text, and a spoken label that names the comparison and, with `better`, the rating. */\nexport function DeltaBadge(props: { delta: StatCellDelta; compare?: StatCellCompare }): JSX.Element {\n const locale = useLocale();\n const t = useStatCellMessages();\n const tone = () => deltaTone(props.delta);\n const text = () => deltaText(props.delta, locale(), t());\n const label = () =>\n [text(), props.compare ? t().comparedWith({ label: props.compare.label }) : \"\"].filter(Boolean).join(\" \") +\n (tone() === \"good\" ? `, ${t().better}` : tone() === \"bad\" ? `, ${t().worse}` : \"\");\n const icon = () => (shownDelta(props.delta) > 0 ? \"ti-trending-up\" : shownDelta(props.delta) < 0 ? \"ti-trending-down\" : \"ti-minus\");\n return (\n <span class=\"k2b-stat-cell__delta\" data-tone={tone()} role=\"img\" aria-label={label()}>\n <i class={`ti ${icon()}`} aria-hidden=\"true\" />\n {text()}\n </span>\n );\n}\n"],"mappings":";;;;;;;;AACA,SAAS,SAAS,QAAQ,gBAAgB;AAE1C,SAAgC,mBAAmB,QAAQ,sBAAsB;;AAEjF;;AAEA;AACA,MAAM,UAAU,GAAI,KAAoB,IAAa,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC;AAE/F,MAAM,SAAS,GAAI,KAAoB,IAAiC;EACtE,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC;EAC/B,OAAO,CAAC,KAAK,CAAC,MAAM,IAAI,KAAK,KAAK,CAAC,GAAG,SAAS,GAAG,KAAK,GAAG,CAAC,MAAM,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC,GAAG,MAAM,GAAG,KAAK;AAC1G,CAAC;;AAED;AACA,OAAO,MAAM,SAAS,GAAG,CAAC,KAAoB,EAAE,MAAc,EAAE,CAAmB,KACjF,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,GACpB,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE;EAAE,qBAAqB,EAAE,CAAC;EAAE,qBAAqB,EAAE,CAAC;EAAE,WAAW,EAAE;AAAa,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,GACjK,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE;EAC5B,KAAK,EAAE,SAAS;EAChB,qBAAqB,EAAE,CAAC;EACxB,qBAAqB,EAAE,CAAC;EACxB,WAAW,EAAE;AACf,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAC9B,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC;;AAE1B;AACA,OAAO,SAAS,UAAU,CAAC,KAA0D,EAAe;EAClG,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC;EAC1B,MAAM,CAAC,GAAG,mBAAmB,CAAC,CAAC;EAC/B,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC;EACzC,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;EACxD,MAAM,KAAK,GAAG,MACZ,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC;IAAE,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC;EAAM,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IACxG,IAAI,CAAC,CAAC,KAAK,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,KAAK,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC;EACpF,MAAM,IAAI,GAAG,MAAO,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,gBAAgB,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,kBAAkB,GAAG,UAAW;EACnI;IAAA;MAAA;MAAA;MAAA;IAAA,eAGK,IAAI;IAAA;MAAA,UAFuC,IAAI,CAAC,CAAC;QAAA,OAAyB,KAAK,CAAC,CAAC;QAAA,OACxE,MAAM,IAAI,CAAC,CAAC,EAAE;MAAA;MAAA;MAAA;MAAA;IAAA;MAAA;MAAA;MAAA;IAAA;IAAA;EAAA;AAI9B","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["surfaces/delta-badge.tsx"],"sourcesContent":["import type { JSX } from \"solid-js\";\nimport { useLocale } from \"../intl/locale\";\nimport type { StatCellCompare, StatCellDelta } from \"./StatCell\";\nimport { type StatCellMessages, useStatCellMessages } from \"./stat-cell-messages\";\n\n// The change badge of a key figure, on its own so a table cell can show it without the tile and its trend chart.\n\n/** The change as shown: one decimal of a percent or point, so text, arrow and rating never disagree. */\nconst shownDelta = (delta: StatCellDelta): number =>\n delta.unit === \"absolute\" ? delta.value || 0 : Math.round(delta.value * 1000) / 1000 || 0;\n\nconst deltaTone = (delta: StatCellDelta): \"good\" | \"bad\" | \"neutral\" => {\n const value = shownDelta(delta);\n return !delta.better || value === 0 ? \"neutral\" : value > 0 === (delta.better === \"up\") ? \"good\" : \"bad\";\n};\n\n/** Signed with a true minus sign (U+2212), as figures are typeset. */\nexport const deltaText = (delta: StatCellDelta, locale: string, t: StatCellMessages): string =>\n (delta.unit === \"absolute\"\n ? `${new Intl.NumberFormat(locale, {\n ...(!delta.format ? { maximumSignificantDigits: 15 } : {}),\n style: delta.format?.style === \"number\" ? \"decimal\" : delta.format?.style,\n currency: delta.format?.currency,\n ...(delta.format?.decimals === undefined\n ? {}\n : { minimumFractionDigits: delta.format.decimals, maximumFractionDigits: delta.format.decimals }),\n ...(delta.format?.compact ? { notation: \"compact\" } : {}),\n signDisplay: \"exceptZero\",\n }).format(delta.value === 0 ? 0 : delta.value)}${delta.format?.unit ? ` ${delta.format.unit}` : \"\"}`\n : delta.unit === \"points\"\n ? `${new Intl.NumberFormat(locale, { minimumFractionDigits: 1, maximumFractionDigits: 1, signDisplay: \"exceptZero\" }).format(shownDelta(delta) * 100)} ${t.points}`\n : new Intl.NumberFormat(locale, {\n style: \"percent\",\n minimumFractionDigits: 1,\n maximumFractionDigits: 1,\n signDisplay: \"exceptZero\",\n }).format(shownDelta(delta))\n ).replace(\"-\", \"\\u2212\");\n\n/** A change badge: arrow, signed text, and a spoken label that names the comparison and, with `better`, the rating. */\nexport function DeltaBadge(props: { delta: StatCellDelta; compare?: StatCellCompare }): JSX.Element {\n const locale = useLocale();\n const t = useStatCellMessages();\n const tone = () => deltaTone(props.delta);\n const text = () => deltaText(props.delta, locale(), t());\n const label = () =>\n [text(), props.compare ? t().comparedWith({ label: props.compare.label }) : \"\"].filter(Boolean).join(\" \") +\n (tone() === \"good\" ? `, ${t().better}` : tone() === \"bad\" ? `, ${t().worse}` : \"\");\n const icon = () => (shownDelta(props.delta) > 0 ? \"ti-trending-up\" : shownDelta(props.delta) < 0 ? \"ti-trending-down\" : \"ti-minus\");\n return (\n <span class=\"k2b-stat-cell__delta\" data-tone={tone()} role=\"img\" aria-label={label()}>\n <i class={`ti ${icon()}`} aria-hidden=\"true\" />\n {text()}\n </span>\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,310 @@
1
+ import { template as _$template } from "solid-js/web";
2
+ import { delegateEvents as _$delegateEvents } from "solid-js/web";
3
+ import { style as _$style } from "solid-js/web";
4
+ import { setAttribute as _$setAttribute } from "solid-js/web";
5
+ import { className as _$className } from "solid-js/web";
6
+ import { effect as _$effect } from "solid-js/web";
7
+ import { getNextMarker as _$getNextMarker } from "solid-js/web";
8
+ import { createComponent as _$createComponent } from "solid-js/web";
9
+ import { memo as _$memo } from "solid-js/web";
10
+ import { getNextElement as _$getNextElement } from "solid-js/web";
11
+ import { runHydrationEvents as _$runHydrationEvents } from "solid-js/web";
12
+ import { insert as _$insert } from "solid-js/web";
13
+ var _tmpl$ = /*#__PURE__*/_$template(`<button type=button class=k2b-dashboard-frame__link>`),
14
+ _tmpl$2 = /*#__PURE__*/_$template(`<div class=k2b-dashboard-frame__tools>`),
15
+ _tmpl$3 = /*#__PURE__*/_$template(`<header class=k2b-dashboard-frame__header><div><!$><!/><p role=status><!$><!/><!$><!/></p></div><!$><!/>`),
16
+ _tmpl$4 = /*#__PURE__*/_$template(`<div class=k2b-dashboard-frame__content>`),
17
+ _tmpl$5 = /*#__PURE__*/_$template(`<div class=k2b-dashboard-frame__stack><div class=k2b-dashboard-frame__reserve aria-hidden=true inert></div><!$><!/>`),
18
+ _tmpl$6 = /*#__PURE__*/_$template(`<div class=k2b-dashboard-frame__skeleton aria-hidden=true><span></span><span>`),
19
+ _tmpl$7 = /*#__PURE__*/_$template(`<p class=k2b-dashboard-frame__inline-state><i aria-hidden=true></i><!$><!/><!$><!/><!$><!/>`),
20
+ _tmpl$8 = /*#__PURE__*/_$template(`<div class=k2b-dashboard-frame__body>`),
21
+ _tmpl$9 = /*#__PURE__*/_$template(`<span class=k2b-chart-explorer__state-icon aria-hidden=true><i>`),
22
+ _tmpl$0 = /*#__PURE__*/_$template(`<i class="ti ti-refresh"aria-hidden=true>`),
23
+ _tmpl$1 = /*#__PURE__*/_$template(`<div class=k2b-chart-explorer__state><!$><!/><p></p><!$><!/><!$><!/>`);
24
+ import { children, Match, Show, Switch } from "solid-js";
25
+ import { Dynamic } from "solid-js/web";
26
+ import { Button } from "../actions/Button";
27
+ import { useChartMessages } from "../content/chart-messages";
28
+ import { useUiMessages } from "../intl/messages";
29
+ import { Paper } from "../surfaces/Paper";
30
+
31
+ /**
32
+ * What the host's read shows: its content (`ready`), the first read in flight (`loading`), nothing to show (`empty`),
33
+ * a failed first read (`error`), or content whose refresh failed (`stale`).
34
+ */
35
+
36
+ /**
37
+ * One framed dashboard panel: title, subtitle, tools and the content the host passes, with loading, empty, failure and
38
+ * stale in the same place and at the same height.
39
+ */
40
+ export function DashboardFrame(props) {
41
+ const ui = useUiMessages();
42
+ const chart = useChartMessages();
43
+ const state = () => props.state ?? "ready";
44
+ const failed = () => state() === "error";
45
+ const read = () => state() === "ready" || state() === "stale";
46
+ const shown = () => read() && !props.emptyContent;
47
+ const empty = () => state() === "empty" || read() && props.emptyContent === true;
48
+ // Slots resolve once: checking a slot and then rendering it must not mount its components twice.
49
+ const tools = children(() => props.tools);
50
+ const reserve = children(() => props.reserve);
51
+ const busy = () => state() === "loading" ? "true" : undefined;
52
+ const className = () => props.class ? `k2b-dashboard-frame ${props.class}` : "k2b-dashboard-frame";
53
+ const retryLink = () => (() => {
54
+ var _el$ = _$getNextElement(_tmpl$);
55
+ _el$.$$click = () => props.onRetry?.();
56
+ _$insert(_el$, () => ui().tryAgain);
57
+ _$runHydrationEvents();
58
+ return _el$;
59
+ })();
60
+ const status = () => state() === "loading" ? chart().chartLoading : state() === "stale" ? [props.asOf ? chart().chartAsOf({
61
+ time: props.asOf
62
+ }) : undefined, chart().chartRefreshFailed].filter(Boolean).join(" · ") : props.subtitle;
63
+ const sentence = () => props.empty ?? ui().noData;
64
+ return _$createComponent(Show, {
65
+ get when() {
66
+ return props.title !== undefined;
67
+ },
68
+ get fallback() {
69
+ return _$createComponent(Paper, {
70
+ get ["class"]() {
71
+ return className();
72
+ },
73
+ get ["data-width"]() {
74
+ return props.width ?? "third";
75
+ },
76
+ get children() {
77
+ return props.children;
78
+ }
79
+ });
80
+ },
81
+ get children() {
82
+ return _$createComponent(Paper, {
83
+ get ["class"]() {
84
+ return className();
85
+ },
86
+ get ["data-width"]() {
87
+ return props.width ?? "third";
88
+ },
89
+ get children() {
90
+ return [(() => {
91
+ var _el$2 = _$getNextElement(_tmpl$3),
92
+ _el$3 = _el$2.firstChild,
93
+ _el$9 = _el$3.firstChild,
94
+ [_el$0, _co$3] = _$getNextMarker(_el$9.nextSibling),
95
+ _el$4 = _el$0.nextSibling,
96
+ _el$5 = _el$4.firstChild,
97
+ [_el$6, _co$] = _$getNextMarker(_el$5.nextSibling),
98
+ _el$7 = _el$6.nextSibling,
99
+ [_el$8, _co$2] = _$getNextMarker(_el$7.nextSibling),
100
+ _el$10 = _el$3.nextSibling,
101
+ [_el$11, _co$4] = _$getNextMarker(_el$10.nextSibling);
102
+ _$insert(_el$3, _$createComponent(Dynamic, {
103
+ get component() {
104
+ return `h${props.headingLevel ?? 3}`;
105
+ },
106
+ get children() {
107
+ return props.title;
108
+ }
109
+ }), _el$0, _co$3);
110
+ _$insert(_el$4, status, _el$6, _co$);
111
+ _$insert(_el$4, _$createComponent(Show, {
112
+ get when() {
113
+ return _$memo(() => state() === "stale")() && props.onRetry;
114
+ },
115
+ get children() {
116
+ return [" · ", _$memo(() => retryLink())];
117
+ }
118
+ }), _el$8, _co$2);
119
+ _$insert(_el$2, _$createComponent(Show, {
120
+ get when() {
121
+ return tools() !== undefined;
122
+ },
123
+ get children() {
124
+ var _el$1 = _$getNextElement(_tmpl$2);
125
+ _$insert(_el$1, tools);
126
+ return _el$1;
127
+ }
128
+ }), _el$11, _co$4);
129
+ _$effect(() => _$className(_el$4, state() === "stale" ? "k2b-dashboard-frame__stale" : undefined));
130
+ return _el$2;
131
+ })(), _$createComponent(Show, {
132
+ get when() {
133
+ return reserve() !== undefined;
134
+ },
135
+ get fallback() {
136
+ return (() => {
137
+ var _el$17 = _$getNextElement(_tmpl$8);
138
+ _$insert(_el$17, _$createComponent(Switch, {
139
+ get fallback() {
140
+ return props.children;
141
+ },
142
+ get children() {
143
+ return [_$createComponent(Match, {
144
+ get when() {
145
+ return _$memo(() => state() === "loading")() && props.compact;
146
+ },
147
+ get children() {
148
+ return _$getNextElement(_tmpl$6);
149
+ }
150
+ }), _$createComponent(Match, {
151
+ get when() {
152
+ return _$memo(() => !!(failed() || empty()))() && props.compact;
153
+ },
154
+ get children() {
155
+ var _el$19 = _$getNextElement(_tmpl$7),
156
+ _el$20 = _el$19.firstChild,
157
+ _el$21 = _el$20.nextSibling,
158
+ [_el$22, _co$6] = _$getNextMarker(_el$21.nextSibling),
159
+ _el$23 = _el$22.nextSibling,
160
+ [_el$24, _co$7] = _$getNextMarker(_el$23.nextSibling),
161
+ _el$25 = _el$24.nextSibling,
162
+ [_el$26, _co$8] = _$getNextMarker(_el$25.nextSibling);
163
+ _$insert(_el$19, (() => {
164
+ var _c$ = _$memo(() => !!failed());
165
+ return () => _c$() ? chart().chartLoadFailed : sentence();
166
+ })(), _el$22, _co$6);
167
+ _$insert(_el$19, _$createComponent(Show, {
168
+ get when() {
169
+ return _$memo(() => !!failed())() && props.onRetry;
170
+ },
171
+ get children() {
172
+ return retryLink();
173
+ }
174
+ }), _el$24, _co$7);
175
+ _$insert(_el$19, _$createComponent(Show, {
176
+ get when() {
177
+ return empty();
178
+ },
179
+ get children() {
180
+ return props.emptyAction;
181
+ }
182
+ }), _el$26, _co$8);
183
+ _$effect(_p$ => {
184
+ var _v$ = failed() ? "alert" : undefined,
185
+ _v$2 = failed() ? "ti ti-alert-circle" : props.emptyIcon ?? "ti ti-chart-bar-off";
186
+ _v$ !== _p$.e && _$setAttribute(_el$19, "role", _p$.e = _v$);
187
+ _v$2 !== _p$.t && _$className(_el$20, _p$.t = _v$2);
188
+ return _p$;
189
+ }, {
190
+ e: undefined,
191
+ t: undefined
192
+ });
193
+ return _el$19;
194
+ }
195
+ }), _$createComponent(Match, {
196
+ get when() {
197
+ return !shown();
198
+ },
199
+ get children() {
200
+ return _$createComponent(Message, {});
201
+ }
202
+ })];
203
+ }
204
+ }));
205
+ _$effect(_p$ => {
206
+ var _v$3 = props.height ? {
207
+ height: props.height
208
+ } : undefined,
209
+ _v$4 = busy();
210
+ _p$.e = _$style(_el$17, _v$3, _p$.e);
211
+ _v$4 !== _p$.t && _$setAttribute(_el$17, "aria-busy", _p$.t = _v$4);
212
+ return _p$;
213
+ }, {
214
+ e: undefined,
215
+ t: undefined
216
+ });
217
+ return _el$17;
218
+ })();
219
+ },
220
+ get children() {
221
+ var _el$12 = _$getNextElement(_tmpl$5),
222
+ _el$13 = _el$12.firstChild,
223
+ _el$15 = _el$13.nextSibling,
224
+ [_el$16, _co$5] = _$getNextMarker(_el$15.nextSibling);
225
+ _$insert(_el$13, reserve);
226
+ _$insert(_el$12, _$createComponent(Show, {
227
+ get when() {
228
+ return shown();
229
+ },
230
+ get fallback() {
231
+ return _$createComponent(Message, {});
232
+ },
233
+ get children() {
234
+ var _el$14 = _$getNextElement(_tmpl$4);
235
+ _$insert(_el$14, () => props.children);
236
+ return _el$14;
237
+ }
238
+ }), _el$16, _co$5);
239
+ _$effect(() => _$setAttribute(_el$12, "aria-busy", busy()));
240
+ return _el$12;
241
+ }
242
+ })];
243
+ }
244
+ });
245
+ }
246
+ });
247
+ function Message() {
248
+ return (() => {
249
+ var _el$27 = _$getNextElement(_tmpl$1),
250
+ _el$32 = _el$27.firstChild,
251
+ [_el$33, _co$9] = _$getNextMarker(_el$32.nextSibling),
252
+ _el$30 = _el$33.nextSibling,
253
+ _el$34 = _el$30.nextSibling,
254
+ [_el$35, _co$0] = _$getNextMarker(_el$34.nextSibling),
255
+ _el$36 = _el$35.nextSibling,
256
+ [_el$37, _co$1] = _$getNextMarker(_el$36.nextSibling);
257
+ _$insert(_el$27, _$createComponent(Show, {
258
+ get when() {
259
+ return state() !== "loading";
260
+ },
261
+ get children() {
262
+ var _el$28 = _$getNextElement(_tmpl$9),
263
+ _el$29 = _el$28.firstChild;
264
+ _$effect(() => _$className(_el$29, failed() ? "ti ti-alert-circle" : props.emptyIcon ?? "ti ti-chart-bar-off"));
265
+ return _el$28;
266
+ }
267
+ }), _el$33, _co$9);
268
+ _$insert(_el$30, (() => {
269
+ var _c$2 = _$memo(() => !!failed());
270
+ return () => _c$2() ? chart().chartLoadFailed : _$memo(() => state() === "loading")() ? "" : sentence();
271
+ })());
272
+ _$insert(_el$27, _$createComponent(Show, {
273
+ get when() {
274
+ return _$memo(() => !!failed())() && props.onRetry;
275
+ },
276
+ get children() {
277
+ return _$createComponent(Button, {
278
+ variant: "secondary",
279
+ size: "sm",
280
+ onClick: () => props.onRetry?.(),
281
+ get children() {
282
+ return [_$getNextElement(_tmpl$0), _$memo(() => ui().tryAgain)];
283
+ }
284
+ });
285
+ }
286
+ }), _el$35, _co$0);
287
+ _$insert(_el$27, _$createComponent(Show, {
288
+ get when() {
289
+ return empty();
290
+ },
291
+ get children() {
292
+ return props.emptyAction;
293
+ }
294
+ }), _el$37, _co$1);
295
+ _$effect(_p$ => {
296
+ var _v$5 = state(),
297
+ _v$6 = failed() ? "alert" : undefined;
298
+ _v$5 !== _p$.e && _$setAttribute(_el$27, "data-state", _p$.e = _v$5);
299
+ _v$6 !== _p$.t && _$setAttribute(_el$27, "role", _p$.t = _v$6);
300
+ return _p$;
301
+ }, {
302
+ e: undefined,
303
+ t: undefined
304
+ });
305
+ return _el$27;
306
+ })();
307
+ }
308
+ }
309
+ _$delegateEvents(["click"]);
310
+ //# sourceMappingURL=DashboardFrame.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["widgets/DashboardFrame.tsx"],"sourcesContent":["import { children, type JSX, Match, Show, Switch } from \"solid-js\";\nimport { Dynamic } from \"solid-js/web\";\nimport { Button } from \"../actions/Button\";\nimport { useChartMessages } from \"../content/chart-messages\";\nimport { useUiMessages } from \"../intl/messages\";\nimport { Paper } from \"../surfaces/Paper\";\nimport type { DashboardWidth } from \"./Dashboard\";\n\n/**\n * What the host's read shows: its content (`ready`), the first read in flight (`loading`), nothing to show (`empty`),\n * a failed first read (`error`), or content whose refresh failed (`stale`).\n */\nexport type DashboardFrameState = \"ready\" | \"loading\" | \"empty\" | \"error\" | \"stale\";\n\nexport type DashboardFrameProps = {\n /**\n * Heading of the frame. Without it the frame is only the surface, for content that brings its own head and states,\n * such as `ChartExplorer` with `inset=\"1rem\"`.\n */\n title?: string;\n /** One line under the title; loading and stale notes take its place, so nothing moves. */\n subtitle?: JSX.Element;\n /** Level of the title heading; defaults to 3. */\n headingLevel?: 2 | 3 | 4 | 5 | 6;\n /** Controls at the right of the head, such as a search field or a grouping chip. */\n tools?: JSX.Element;\n /** Defaults to `ready`. */\n state?: DashboardFrameState;\n /** When the shown content was read, formatted by the host (\"09:12\"); a stale note names it. */\n asOf?: string;\n /** Try again after a failure; without it a failure has no button. */\n onRetry?: () => void;\n /** The empty sentence, such as \"No campaign in this period.\" */\n empty?: JSX.Element;\n /** Tabler icon of the empty state; defaults to `ti ti-chart-bar-off`. */\n emptyIcon?: string;\n /** An action under the empty sentence, such as \"Clear search\". */\n emptyAction?: JSX.Element;\n /**\n * The content has nothing to show right now although the read succeeded, such as a search without matches: the body\n * shows the empty sentence and action while the head keeps its state, so a stale note stays.\n */\n emptyContent?: boolean;\n /** Height of the body, a CSS length. Every state keeps it. */\n height?: string;\n /**\n * A hidden copy of the full content that holds the body's height in every state, such as every row of a table. The\n * body then reaches the frame's left, right and bottom edges, like a table that brings its own rows.\n */\n reserve?: JSX.Element;\n /** States as one quiet line instead of a centred message, for short content such as an amount or one bar. */\n compact?: boolean;\n /**\n * Share of a `DashboardSection`'s six columns, like `DashboardPanel`: the frame is the grid cell itself, so it never\n * sits in a second frame. Defaults to a third there; ignored elsewhere.\n */\n width?: DashboardWidth;\n class?: string;\n children?: JSX.Element;\n};\n\n/**\n * One framed dashboard panel: title, subtitle, tools and the content the host passes, with loading, empty, failure and\n * stale in the same place and at the same height.\n */\nexport function DashboardFrame(props: DashboardFrameProps): JSX.Element {\n const ui = useUiMessages();\n const chart = useChartMessages();\n const state = () => props.state ?? \"ready\";\n const failed = () => state() === \"error\";\n const read = () => state() === \"ready\" || state() === \"stale\";\n const shown = () => read() && !props.emptyContent;\n const empty = () => state() === \"empty\" || (read() && props.emptyContent === true);\n // Slots resolve once: checking a slot and then rendering it must not mount its components twice.\n const tools = children(() => props.tools);\n const reserve = children(() => props.reserve);\n const busy = () => (state() === \"loading\" ? \"true\" : undefined);\n const className = () => (props.class ? `k2b-dashboard-frame ${props.class}` : \"k2b-dashboard-frame\");\n const retryLink = () => (\n <button type=\"button\" class=\"k2b-dashboard-frame__link\" onClick={() => props.onRetry?.()}>\n {ui().tryAgain}\n </button>\n );\n const status = () =>\n state() === \"loading\"\n ? chart().chartLoading\n : state() === \"stale\"\n ? [props.asOf ? chart().chartAsOf({ time: props.asOf }) : undefined, chart().chartRefreshFailed].filter(Boolean).join(\" · \")\n : props.subtitle;\n const sentence = () => props.empty ?? ui().noData;\n return (\n <Show\n when={props.title !== undefined}\n fallback={\n <Paper class={className()} data-width={props.width ?? \"third\"}>\n {props.children}\n </Paper>\n }\n >\n <Paper class={className()} data-width={props.width ?? \"third\"}>\n <header class=\"k2b-dashboard-frame__header\">\n <div>\n <Dynamic component={`h${props.headingLevel ?? 3}`}>{props.title}</Dynamic>\n {/* One reserved line and a polite live region: loading and stale replace the subtitle without moving. */}\n <p role=\"status\" class={state() === \"stale\" ? \"k2b-dashboard-frame__stale\" : undefined}>\n {status()}\n <Show when={state() === \"stale\" && props.onRetry}>\n {\" · \"}\n {retryLink()}\n </Show>\n </p>\n </div>\n <Show when={tools() !== undefined}>\n <div class=\"k2b-dashboard-frame__tools\">{tools()}</div>\n </Show>\n </header>\n <Show\n when={reserve() !== undefined}\n fallback={\n <div class=\"k2b-dashboard-frame__body\" style={props.height ? { height: props.height } : undefined} aria-busy={busy()}>\n <Switch fallback={props.children}>\n <Match when={state() === \"loading\" && props.compact}>\n <div class=\"k2b-dashboard-frame__skeleton\" aria-hidden=\"true\">\n <span />\n <span />\n </div>\n </Match>\n <Match when={(failed() || empty()) && props.compact}>\n <p class=\"k2b-dashboard-frame__inline-state\" role={failed() ? \"alert\" : undefined}>\n <i class={failed() ? \"ti ti-alert-circle\" : (props.emptyIcon ?? \"ti ti-chart-bar-off\")} aria-hidden=\"true\" />\n {failed() ? chart().chartLoadFailed : sentence()}\n <Show when={failed() && props.onRetry}>{retryLink()}</Show>\n <Show when={empty()}>{props.emptyAction}</Show>\n </p>\n </Match>\n <Match when={!shown()}>\n <Message />\n </Match>\n </Switch>\n </div>\n }\n >\n <div class=\"k2b-dashboard-frame__stack\" aria-busy={busy()}>\n {/* The full content, hidden: the body's height in every state. */}\n <div class=\"k2b-dashboard-frame__reserve\" aria-hidden=\"true\" inert>\n {reserve()}\n </div>\n <Show when={shown()} fallback={<Message />}>\n <div class=\"k2b-dashboard-frame__content\">{props.children}</div>\n </Show>\n </div>\n </Show>\n </Paper>\n </Show>\n );\n\n function Message(): JSX.Element {\n return (\n <div class=\"k2b-chart-explorer__state\" data-state={state()} role={failed() ? \"alert\" : undefined}>\n <Show when={state() !== \"loading\"}>\n <span class=\"k2b-chart-explorer__state-icon\" aria-hidden=\"true\">\n <i class={failed() ? \"ti ti-alert-circle\" : (props.emptyIcon ?? \"ti ti-chart-bar-off\")} />\n </span>\n </Show>\n <p>{failed() ? chart().chartLoadFailed : state() === \"loading\" ? \"\" : sentence()}</p>\n <Show when={failed() && props.onRetry}>\n <Button variant=\"secondary\" size=\"sm\" onClick={() => props.onRetry?.()}>\n <i class=\"ti ti-refresh\" aria-hidden=\"true\" />\n {ui().tryAgain}\n </Button>\n </Show>\n <Show when={empty()}>{props.emptyAction}</Show>\n </div>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,4 +1,5 @@
1
1
  export * from "./Dashboard";
2
+ export * from "./DashboardFrame";
2
3
  export * from "./Widget";
3
4
  export * from "./WidgetHero";
4
5
  export * from "./WidgetList";
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["widgets/index.ts"],"sourcesContent":["export * from \"./Dashboard\";\nexport * from \"./Widget\";\nexport * from \"./WidgetHero\";\nexport * from \"./WidgetList\";\nexport * from \"./WidgetPills\";\nexport * from \"./WidgetStat\";\nexport * from \"./WidgetStatus\";\n"],"mappings":"AAAA,cAAc,aAAa;AAC3B,cAAc,UAAU;AACxB,cAAc,cAAc;AAC5B,cAAc,cAAc;AAC5B,cAAc,eAAe;AAC7B,cAAc,cAAc;AAC5B,cAAc,gBAAgB","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["widgets/index.ts"],"sourcesContent":["export * from \"./Dashboard\";\nexport * from \"./DashboardFrame\";\nexport * from \"./Widget\";\nexport * from \"./WidgetHero\";\nexport * from \"./WidgetList\";\nexport * from \"./WidgetPills\";\nexport * from \"./WidgetStat\";\nexport * from \"./WidgetStatus\";\n"],"mappings":"AAAA,cAAc,aAAa;AAC3B,cAAc,kBAAkB;AAChC,cAAc,UAAU;AACxB,cAAc,cAAc;AAC5B,cAAc,cAAc;AAC5B,cAAc,eAAe;AAC7B,cAAc,cAAc;AAC5B,cAAc,gBAAgB","ignoreList":[]}