@epilot/spark-ui 0.19.0 → 0.20.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 (275) hide show
  1. package/dist/components/accordion.cjs +2 -2
  2. package/dist/components/accordion.d.ts +1 -1
  3. package/dist/components/accordion.js +1 -1
  4. package/dist/components/alert-dialog.cjs +1 -1
  5. package/dist/components/alert-dialog.js +1 -1
  6. package/dist/components/attachment.d.cts +2 -2
  7. package/dist/components/attachment.d.ts +2 -2
  8. package/dist/components/autocomplete.cjs +1 -1
  9. package/dist/components/autocomplete.js +1 -1
  10. package/dist/components/avatar.cjs +1 -1
  11. package/dist/components/avatar.cjs.map +1 -1
  12. package/dist/components/avatar.js +1 -1
  13. package/dist/components/avatar.js.map +1 -1
  14. package/dist/components/badge.cjs +1 -1
  15. package/dist/components/badge.cjs.map +1 -1
  16. package/dist/components/badge.d.cts +2 -1
  17. package/dist/components/badge.d.ts +2 -1
  18. package/dist/components/badge.js +1 -1
  19. package/dist/components/badge.js.map +1 -1
  20. package/dist/components/{energy-bar-chart.cjs → bar-chart-with-total.cjs} +4 -4
  21. package/dist/components/bar-chart-with-total.cjs.map +1 -0
  22. package/dist/components/bar-chart-with-total.d.cts +19 -0
  23. package/dist/components/bar-chart-with-total.d.ts +19 -0
  24. package/dist/components/{energy-bar-chart.js → bar-chart-with-total.js} +4 -4
  25. package/dist/components/bar-chart-with-total.js.map +1 -0
  26. package/dist/components/bubble.d.cts +1 -1
  27. package/dist/components/bubble.d.ts +1 -1
  28. package/dist/components/button-group.cjs +2 -2
  29. package/dist/components/button-group.cjs.map +1 -1
  30. package/dist/components/button-group.d.cts +1 -1
  31. package/dist/components/button-group.d.ts +1 -1
  32. package/dist/components/button-group.js +2 -2
  33. package/dist/components/button-group.js.map +1 -1
  34. package/dist/components/button.cjs +6 -4
  35. package/dist/components/button.cjs.map +1 -1
  36. package/dist/components/button.d.cts +6 -5
  37. package/dist/components/button.d.ts +6 -5
  38. package/dist/components/button.js +6 -4
  39. package/dist/components/button.js.map +1 -1
  40. package/dist/components/calendar.cjs +3 -3
  41. package/dist/components/calendar.cjs.map +1 -1
  42. package/dist/components/calendar.js +3 -3
  43. package/dist/components/calendar.js.map +1 -1
  44. package/dist/components/callout.cjs +11 -11
  45. package/dist/components/callout.cjs.map +1 -1
  46. package/dist/components/callout.d.ts +1 -1
  47. package/dist/components/callout.js +11 -11
  48. package/dist/components/callout.js.map +1 -1
  49. package/dist/components/checkbox.cjs +1 -1
  50. package/dist/components/checkbox.cjs.map +1 -1
  51. package/dist/components/checkbox.js +1 -1
  52. package/dist/components/checkbox.js.map +1 -1
  53. package/dist/components/circular-gauge.cjs +7 -7
  54. package/dist/components/circular-gauge.cjs.map +1 -1
  55. package/dist/components/circular-gauge.js +7 -7
  56. package/dist/components/circular-gauge.js.map +1 -1
  57. package/dist/components/day-of-week-picker.cjs +21 -41
  58. package/dist/components/day-of-week-picker.cjs.map +1 -1
  59. package/dist/components/day-of-week-picker.d.cts +19 -23
  60. package/dist/components/day-of-week-picker.d.ts +19 -23
  61. package/dist/components/day-of-week-picker.js +21 -41
  62. package/dist/components/day-of-week-picker.js.map +1 -1
  63. package/dist/components/dialog.cjs +1 -1
  64. package/dist/components/dialog.js +1 -1
  65. package/dist/components/dropdown-menu.cjs +1 -1
  66. package/dist/components/dropdown-menu.js +1 -1
  67. package/dist/components/empty-state.d.ts +1 -1
  68. package/dist/components/{device-card.cjs → entity-card.cjs} +31 -31
  69. package/dist/components/entity-card.cjs.map +1 -0
  70. package/dist/components/{device-card.d.cts → entity-card.d.cts} +15 -15
  71. package/dist/components/{device-card.d.ts → entity-card.d.ts} +16 -16
  72. package/dist/components/{device-card.js → entity-card.js} +20 -20
  73. package/dist/components/entity-card.js.map +1 -0
  74. package/dist/components/{feed-in-hero.cjs → hero-metric.cjs} +10 -15
  75. package/dist/components/hero-metric.cjs.map +1 -0
  76. package/dist/components/hero-metric.d.cts +27 -0
  77. package/dist/components/hero-metric.d.ts +27 -0
  78. package/dist/components/{feed-in-hero.js → hero-metric.js} +7 -12
  79. package/dist/components/hero-metric.js.map +1 -0
  80. package/dist/components/info-block.d.cts +1 -1
  81. package/dist/components/info-block.d.ts +1 -1
  82. package/dist/components/input-date.cjs +1 -1
  83. package/dist/components/input-date.js +1 -1
  84. package/dist/components/input-otp.cjs +1 -1
  85. package/dist/components/input-otp.js +1 -1
  86. package/dist/components/input.cjs +1 -1
  87. package/dist/components/input.js +1 -1
  88. package/dist/components/line-chart.cjs +1 -1
  89. package/dist/components/line-chart.js +1 -1
  90. package/dist/components/marker.d.cts +1 -1
  91. package/dist/components/marker.d.ts +1 -1
  92. package/dist/components/message-scroller.cjs +3 -3
  93. package/dist/components/message-scroller.js +3 -3
  94. package/dist/components/number-flow.d.cts +12 -2
  95. package/dist/components/number-flow.d.ts +12 -2
  96. package/dist/components/page-header.cjs +1 -1
  97. package/dist/components/page-header.js +1 -1
  98. package/dist/components/period-tabs.cjs +2 -22
  99. package/dist/components/period-tabs.cjs.map +1 -1
  100. package/dist/components/period-tabs.d.cts +5 -22
  101. package/dist/components/period-tabs.d.ts +5 -22
  102. package/dist/components/period-tabs.js +2 -22
  103. package/dist/components/period-tabs.js.map +1 -1
  104. package/dist/components/pill.cjs +3 -3
  105. package/dist/components/pill.cjs.map +1 -1
  106. package/dist/components/pill.js +3 -3
  107. package/dist/components/pill.js.map +1 -1
  108. package/dist/components/progress.cjs +1 -1
  109. package/dist/components/progress.cjs.map +1 -1
  110. package/dist/components/progress.js +1 -1
  111. package/dist/components/progress.js.map +1 -1
  112. package/dist/components/radio.cjs +1 -1
  113. package/dist/components/radio.cjs.map +1 -1
  114. package/dist/components/radio.js +1 -1
  115. package/dist/components/radio.js.map +1 -1
  116. package/dist/components/sankey-chart.cjs +1 -11
  117. package/dist/components/sankey-chart.cjs.map +1 -1
  118. package/dist/components/sankey-chart.d.cts +2 -3
  119. package/dist/components/sankey-chart.d.ts +2 -3
  120. package/dist/components/sankey-chart.js +2 -11
  121. package/dist/components/sankey-chart.js.map +1 -1
  122. package/dist/components/schedule-list.cjs +1 -1
  123. package/dist/components/schedule-list.js +1 -1
  124. package/dist/components/segmented-control.cjs +2 -2
  125. package/dist/components/segmented-control.cjs.map +1 -1
  126. package/dist/components/segmented-control.js +2 -2
  127. package/dist/components/segmented-control.js.map +1 -1
  128. package/dist/components/select.cjs +33 -3
  129. package/dist/components/select.cjs.map +1 -1
  130. package/dist/components/select.d.cts +11 -1
  131. package/dist/components/select.d.ts +11 -1
  132. package/dist/components/select.js +32 -4
  133. package/dist/components/select.js.map +1 -1
  134. package/dist/components/sheet.cjs +1 -1
  135. package/dist/components/sheet.js +1 -1
  136. package/dist/components/stepper.cjs +2 -2
  137. package/dist/components/stepper.cjs.map +1 -1
  138. package/dist/components/stepper.d.cts +4 -4
  139. package/dist/components/stepper.d.ts +4 -4
  140. package/dist/components/stepper.js +2 -2
  141. package/dist/components/stepper.js.map +1 -1
  142. package/dist/components/table.cjs +1 -1
  143. package/dist/components/table.js +1 -1
  144. package/dist/components/tabs.cjs +1 -1
  145. package/dist/components/tabs.js +1 -1
  146. package/dist/components/textarea.cjs +1 -1
  147. package/dist/components/textarea.js +1 -1
  148. package/dist/components/toast.cjs +1 -1
  149. package/dist/components/toast.js +1 -1
  150. package/dist/components/tooltip.cjs +2 -2
  151. package/dist/components/tooltip.cjs.map +1 -1
  152. package/dist/components/tooltip.js +2 -2
  153. package/dist/components/tooltip.js.map +1 -1
  154. package/dist/components/typography.cjs +1 -1
  155. package/dist/components/typography.cjs.map +1 -1
  156. package/dist/components/typography.d.cts +4 -1
  157. package/dist/components/typography.d.ts +4 -1
  158. package/dist/components/typography.js +1 -1
  159. package/dist/components/typography.js.map +1 -1
  160. package/dist/components/wizard-layout.cjs +57 -0
  161. package/dist/components/wizard-layout.cjs.map +1 -0
  162. package/dist/components/wizard-layout.d.cts +34 -0
  163. package/dist/components/wizard-layout.d.ts +34 -0
  164. package/dist/components/wizard-layout.js +50 -0
  165. package/dist/components/wizard-layout.js.map +1 -0
  166. package/dist/lib/accent-colors.cjs +4 -1
  167. package/dist/lib/accent-colors.cjs.map +1 -1
  168. package/dist/lib/accent-colors.d.cts +1 -1
  169. package/dist/lib/accent-colors.d.ts +1 -1
  170. package/dist/lib/accent-colors.js +4 -1
  171. package/dist/lib/accent-colors.js.map +1 -1
  172. package/dist/lib/accent-theme.cjs +2 -2
  173. package/dist/lib/accent-theme.cjs.map +1 -1
  174. package/dist/lib/accent-theme.js +2 -2
  175. package/dist/lib/accent-theme.js.map +1 -1
  176. package/dist/styles/index.css +1 -1
  177. package/dist/styles/spark-default.css +49 -314
  178. package/dist/styles/theme.css +52 -6
  179. package/dist/utils/format.cjs +0 -13
  180. package/dist/utils/format.cjs.map +1 -1
  181. package/dist/utils/format.d.cts +1 -7
  182. package/dist/utils/format.d.ts +1 -7
  183. package/dist/utils/format.js +1 -12
  184. package/dist/utils/format.js.map +1 -1
  185. package/package.json +1 -1
  186. package/dist/components/battery-progress-row.cjs +0 -135
  187. package/dist/components/battery-progress-row.cjs.map +0 -1
  188. package/dist/components/battery-progress-row.d.cts +0 -69
  189. package/dist/components/battery-progress-row.d.ts +0 -69
  190. package/dist/components/battery-progress-row.js +0 -125
  191. package/dist/components/battery-progress-row.js.map +0 -1
  192. package/dist/components/device-card.cjs.map +0 -1
  193. package/dist/components/device-card.js.map +0 -1
  194. package/dist/components/energy-bar-chart.cjs.map +0 -1
  195. package/dist/components/energy-bar-chart.d.cts +0 -43
  196. package/dist/components/energy-bar-chart.d.ts +0 -43
  197. package/dist/components/energy-bar-chart.js.map +0 -1
  198. package/dist/components/energy-breakdown.cjs +0 -80
  199. package/dist/components/energy-breakdown.cjs.map +0 -1
  200. package/dist/components/energy-breakdown.d.cts +0 -24
  201. package/dist/components/energy-breakdown.d.ts +0 -24
  202. package/dist/components/energy-breakdown.js +0 -79
  203. package/dist/components/energy-breakdown.js.map +0 -1
  204. package/dist/components/energy-history-chart.cjs +0 -63
  205. package/dist/components/energy-history-chart.cjs.map +0 -1
  206. package/dist/components/energy-history-chart.d.cts +0 -64
  207. package/dist/components/energy-history-chart.d.ts +0 -64
  208. package/dist/components/energy-history-chart.js +0 -62
  209. package/dist/components/energy-history-chart.js.map +0 -1
  210. package/dist/components/feed-in-hero.cjs.map +0 -1
  211. package/dist/components/feed-in-hero.d.cts +0 -32
  212. package/dist/components/feed-in-hero.d.ts +0 -32
  213. package/dist/components/feed-in-hero.js.map +0 -1
  214. package/dist/components/metering-row.cjs +0 -59
  215. package/dist/components/metering-row.cjs.map +0 -1
  216. package/dist/components/metering-row.d.cts +0 -31
  217. package/dist/components/metering-row.d.ts +0 -31
  218. package/dist/components/metering-row.js +0 -55
  219. package/dist/components/metering-row.js.map +0 -1
  220. package/dist/components/money-saved-block.cjs +0 -83
  221. package/dist/components/money-saved-block.cjs.map +0 -1
  222. package/dist/components/money-saved-block.d.cts +0 -55
  223. package/dist/components/money-saved-block.d.ts +0 -55
  224. package/dist/components/money-saved-block.js +0 -76
  225. package/dist/components/money-saved-block.js.map +0 -1
  226. package/dist/components/on-off-button.cjs +0 -32
  227. package/dist/components/on-off-button.cjs.map +0 -1
  228. package/dist/components/on-off-button.d.cts +0 -18
  229. package/dist/components/on-off-button.d.ts +0 -18
  230. package/dist/components/on-off-button.js +0 -31
  231. package/dist/components/on-off-button.js.map +0 -1
  232. package/dist/components/onboarding-layout.cjs +0 -67
  233. package/dist/components/onboarding-layout.cjs.map +0 -1
  234. package/dist/components/onboarding-layout.d.cts +0 -44
  235. package/dist/components/onboarding-layout.d.ts +0 -44
  236. package/dist/components/onboarding-layout.js +0 -60
  237. package/dist/components/onboarding-layout.js.map +0 -1
  238. package/dist/components/power-history-chart.cjs +0 -498
  239. package/dist/components/power-history-chart.cjs.map +0 -1
  240. package/dist/components/power-history-chart.d.cts +0 -71
  241. package/dist/components/power-history-chart.d.ts +0 -71
  242. package/dist/components/power-history-chart.js +0 -496
  243. package/dist/components/power-history-chart.js.map +0 -1
  244. package/dist/components/power-history.cjs +0 -114
  245. package/dist/components/power-history.cjs.map +0 -1
  246. package/dist/components/power-history.d.cts +0 -40
  247. package/dist/components/power-history.d.ts +0 -41
  248. package/dist/components/power-history.js +0 -114
  249. package/dist/components/power-history.js.map +0 -1
  250. package/dist/components/power-network.cjs +0 -559
  251. package/dist/components/power-network.cjs.map +0 -1
  252. package/dist/components/power-network.d.cts +0 -80
  253. package/dist/components/power-network.d.ts +0 -80
  254. package/dist/components/power-network.js +0 -553
  255. package/dist/components/power-network.js.map +0 -1
  256. package/dist/components/smart-toggle-button.cjs +0 -24
  257. package/dist/components/smart-toggle-button.cjs.map +0 -1
  258. package/dist/components/smart-toggle-button.d.cts +0 -16
  259. package/dist/components/smart-toggle-button.d.ts +0 -16
  260. package/dist/components/smart-toggle-button.js +0 -23
  261. package/dist/components/smart-toggle-button.js.map +0 -1
  262. package/dist/components/solar-forecast-chart.cjs +0 -108
  263. package/dist/components/solar-forecast-chart.cjs.map +0 -1
  264. package/dist/components/solar-forecast-chart.d.cts +0 -77
  265. package/dist/components/solar-forecast-chart.d.ts +0 -77
  266. package/dist/components/solar-forecast-chart.js +0 -103
  267. package/dist/components/solar-forecast-chart.js.map +0 -1
  268. package/dist/number-flow-Bch81ixZ.d.cts +0 -14
  269. package/dist/number-flow-Bch81ixZ.d.ts +0 -14
  270. package/dist/utils/build-sankey-nodes.cjs +0 -72
  271. package/dist/utils/build-sankey-nodes.cjs.map +0 -1
  272. package/dist/utils/build-sankey-nodes.d.cts +0 -27
  273. package/dist/utils/build-sankey-nodes.d.ts +0 -27
  274. package/dist/utils/build-sankey-nodes.js +0 -71
  275. package/dist/utils/build-sankey-nodes.js.map +0 -1
@@ -1,16 +0,0 @@
1
- "use client";
2
-
3
- //#region src/components/smart-toggle-button.d.ts
4
- interface SmartToggleButtonProps {
5
- active: boolean;
6
- disabled?: boolean;
7
- onClick: () => void;
8
- }
9
- declare function SmartToggleButton({
10
- active,
11
- disabled,
12
- onClick
13
- }: SmartToggleButtonProps): import("react/jsx-runtime").JSX.Element;
14
- //#endregion
15
- export { SmartToggleButton };
16
- //# sourceMappingURL=smart-toggle-button.d.cts.map
@@ -1,16 +0,0 @@
1
- "use client";
2
-
3
- //#region src/components/smart-toggle-button.d.ts
4
- interface SmartToggleButtonProps {
5
- active: boolean;
6
- disabled?: boolean;
7
- onClick: () => void;
8
- }
9
- declare function SmartToggleButton({
10
- active,
11
- disabled,
12
- onClick
13
- }: SmartToggleButtonProps): import("react/jsx-runtime").JSX.Element;
14
- //#endregion
15
- export { SmartToggleButton };
16
- //# sourceMappingURL=smart-toggle-button.d.ts.map
@@ -1,23 +0,0 @@
1
- "use client";
2
- import { cn } from "../utils/cn.js";
3
- import { WandStars } from "@epilot/spark-icons";
4
- import { jsx, jsxs } from "react/jsx-runtime";
5
- //#region src/components/smart-toggle-button.tsx
6
- function SmartToggleButton({ active, disabled, onClick }) {
7
- const handleClick = (event) => {
8
- event.stopPropagation();
9
- onClick();
10
- };
11
- return /* @__PURE__ */ jsxs("button", {
12
- "aria-pressed": active,
13
- className: cn("touch-target inline-flex min-w-9 cursor-pointer items-center gap-1.5 rounded-[max(var(--spark-rounded-md),var(--spark-rounded-full))] px-3 text-sm font-medium transition-colors max-sm:h-10 md:h-9 focus-visible:ring-primary focus-visible:ring-2 focus-visible:outline-none disabled:opacity-60 disabled:cursor-not-allowed", active ? "bg-base-accent-soft text-accent border border-transparent hover:bg-base-accent-soft/80" : "border-gray text-gray-light border hover:bg-base-gray-soft"),
14
- disabled,
15
- onClick: handleClick,
16
- type: "button",
17
- children: [/* @__PURE__ */ jsx(WandStars, { className: "block leading-none [--spark-icon-size:16px]" }), "Smart"]
18
- });
19
- }
20
- //#endregion
21
- export { SmartToggleButton };
22
-
23
- //# sourceMappingURL=smart-toggle-button.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"smart-toggle-button.js","names":[],"sources":["../../src/components/smart-toggle-button.tsx"],"sourcesContent":["import { WandStars } from '@epilot/spark-icons'\nimport type { MouseEvent } from 'react'\nimport { cn } from '../utils/cn'\n\ninterface SmartToggleButtonProps {\n active: boolean\n disabled?: boolean\n onClick: () => void\n}\n\nexport function SmartToggleButton({\n active,\n disabled,\n onClick,\n}: SmartToggleButtonProps) {\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n event.stopPropagation()\n onClick()\n }\n\n const base =\n 'touch-target inline-flex min-w-9 cursor-pointer items-center gap-1.5 rounded-[max(var(--spark-rounded-md),var(--spark-rounded-full))] px-3 text-sm font-medium transition-colors max-sm:h-10 md:h-9 focus-visible:ring-primary focus-visible:ring-2 focus-visible:outline-none disabled:opacity-60 disabled:cursor-not-allowed'\n const tone = active\n ? 'bg-base-accent-soft text-accent border border-transparent hover:bg-base-accent-soft/80'\n : 'border-gray text-gray-light border hover:bg-base-gray-soft'\n\n return (\n <button\n aria-pressed={active}\n className={cn(base, tone)}\n disabled={disabled}\n onClick={handleClick}\n type=\"button\"\n >\n <WandStars className=\"block leading-none [--spark-icon-size:16px]\" />\n Smart\n </button>\n )\n}\n"],"mappings":";;;;;AAUA,SAAgB,kBAAkB,EAChC,QACA,UACA,WACyB;CACzB,MAAM,eAAe,UAAyC;EAC5D,MAAM,gBAAgB;EACtB,QAAQ;CACV;CAQA,OACE,qBAAC,UAAD;EACE,gBAAc;EACd,WAAW,GAAG,kUAPL,SACT,2FACA,4DAKwB;EACd;EACV,SAAS;EACT,MAAK;YALP,CAOE,oBAAC,WAAD,EAAW,WAAU,8CAA+C,CAAA,GAAC,OAE/D;;AAEZ"}
@@ -1,108 +0,0 @@
1
- "use client";
2
- Object.defineProperties(exports, {
3
- __esModule: { value: true },
4
- [Symbol.toStringTag]: { value: "Module" }
5
- });
6
- require("../utils/chars.cjs");
7
- const require_utils_format = require("../utils/format.cjs");
8
- const require_components_line_chart = require("./line-chart.cjs");
9
- let react = require("react");
10
- let react_jsx_runtime = require("react/jsx-runtime");
11
- let cnfast = require("cnfast");
12
- //#region src/components/solar-forecast-chart.tsx
13
- const DEFAULT_HEIGHT = 220;
14
- const BASE_MARGIN = {
15
- top: 8,
16
- right: 8,
17
- bottom: 28,
18
- left: 34
19
- };
20
- /** Extra headroom for the weather icon row pinned above the plot. */
21
- const WEATHER_ROW_HEIGHT = 24;
22
- function defaultFormatValue(value) {
23
- return `${require_utils_format.oneDecimalFormat.format(value)} kW`;
24
- }
25
- function defaultFormatTime(date) {
26
- return date.getHours().toString().padStart(2, "0");
27
- }
28
- /**
29
- * Responsive line plot of measured production (solid) against a forecast
30
- * (dashed) over a day. Optionally overlays hourly weather icons and
31
- * sunrise/sunset markers, all pinned to the same time axis. Sizes itself to its
32
- * container; compose a title and any summary around it.
33
- */
34
- function SolarForecastChart({ produced, forecast, producedLabel = "Produced", forecastLabel = "Forecast", formatValue = defaultFormatValue, yAxisUnit = "kW", formatTime = defaultFormatTime, formatTooltipTime, weather, sunrise, sunset, formatMarkerTime, curve = "monotone", height = DEFAULT_HEIGHT, className, zoomable, zoomResetLabel, zoomDomain, onZoomDomainChange }) {
35
- const containerRef = (0, react.useRef)(null);
36
- const [width, setWidth] = (0, react.useState)(0);
37
- (0, react.useEffect)(() => {
38
- const el = containerRef.current;
39
- if (!el) return;
40
- const ro = new ResizeObserver((entries) => {
41
- const entry = entries[0];
42
- if (entry) setWidth(entry.contentRect.width);
43
- });
44
- ro.observe(el);
45
- return () => ro.disconnect();
46
- }, []);
47
- const hasWeather = weather != null && weather.length > 0;
48
- const margin = {
49
- ...BASE_MARGIN,
50
- top: hasWeather ? BASE_MARGIN.top + WEATHER_ROW_HEIGHT : BASE_MARGIN.top
51
- };
52
- const formatMarker = formatMarkerTime ?? formatTooltipTime ?? formatTime;
53
- const topContent = hasWeather ? weather.map((point, i) => {
54
- const WeatherGlyph = point.icon;
55
- return {
56
- key: `weather-${point.date.valueOf()}-${i}`,
57
- date: point.date,
58
- content: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(WeatherGlyph, { className: "text-gray-light [--spark-icon-size:18px]" })
59
- };
60
- }) : void 0;
61
- const referenceLines = [sunrise && {
62
- key: "sunrise",
63
- date: sunrise,
64
- label: formatMarker(sunrise)
65
- }, sunset && {
66
- key: "sunset",
67
- date: sunset,
68
- label: formatMarker(sunset)
69
- }].filter((x) => Boolean(x));
70
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
71
- ref: containerRef,
72
- className: (0, cnfast.cn)("w-full", className),
73
- children: width > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_components_line_chart.LineChart, {
74
- width,
75
- height,
76
- margin,
77
- curve,
78
- series: [{
79
- id: "produced",
80
- data: produced,
81
- label: producedLabel
82
- }, {
83
- id: "forecast",
84
- data: forecast,
85
- label: forecastLabel,
86
- dashed: true
87
- }],
88
- showGrid: true,
89
- xTickCount: 6,
90
- yTickCount: 4,
91
- yAxisUnit,
92
- formatDate: formatTime,
93
- formatTooltipDate: formatTooltipTime ?? formatTime,
94
- formatValue,
95
- referenceLines: referenceLines.length > 0 ? referenceLines : void 0,
96
- topContent,
97
- zoomable,
98
- zoomResetLabel,
99
- zoomDomain,
100
- onZoomDomainChange
101
- })
102
- });
103
- }
104
- //#endregion
105
- exports.SolarForecastChart = SolarForecastChart;
106
- exports.default = SolarForecastChart;
107
-
108
- //# sourceMappingURL=solar-forecast-chart.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"solar-forecast-chart.cjs","names":["oneDecimalFormat","LineChart"],"sources":["../../src/components/solar-forecast-chart.tsx"],"sourcesContent":["import type { SparkIcon } from '@epilot/spark-icons'\nimport { type JSX, type ReactNode, useEffect, useRef, useState } from 'react'\nimport { NARROW_NBSP } from '../utils/chars'\nimport { cn } from '../utils/cn'\nimport { oneDecimalFormat } from '../utils/format'\nimport {\n LineChart,\n type LineChartCurve,\n type LineChartDatum,\n} from './line-chart'\n\nconst DEFAULT_HEIGHT = 220\n// `left` leaves room for the y-axis tick labels + unit (matches the 34px gutter\n// used by BarChart / PowerHistoryChart).\nconst BASE_MARGIN = { top: 8, right: 8, bottom: 28, left: 34 }\n/** Extra headroom for the weather icon row pinned above the plot. */\nconst WEATHER_ROW_HEIGHT = 24\n\nfunction defaultFormatValue(value: number): string {\n return `${oneDecimalFormat.format(value)}${NARROW_NBSP}kW`\n}\n\nfunction defaultFormatTime(date: Date): string {\n return date.getHours().toString().padStart(2, '0')\n}\n\nexport interface SolarForecastWeatherPoint {\n date: Date\n icon: SparkIcon\n}\n\nexport interface SolarForecastChartProps {\n /** Measured production, drawn as the solid line. */\n produced: LineChartDatum[]\n /** Predicted production, drawn as the dashed line. */\n forecast: LineChartDatum[]\n /** Tooltip label for the produced series. */\n producedLabel?: ReactNode\n /** Tooltip label for the forecast series. */\n forecastLabel?: ReactNode\n /** Tooltip value formatter. Defaults to one-decimal kW (power). */\n formatValue?: (value: number) => string\n /** Unit shown once atop the y-axis; ticks render as plain numbers. Defaults to \"kW\". */\n yAxisUnit?: string\n /** X-axis tick formatter. Defaults to the zero-padded hour. */\n formatTime?: (date: Date) => string\n /** Tooltip time formatter. Defaults to `formatTime`. */\n formatTooltipTime?: (date: Date) => string\n /**\n * Hourly weather icons drawn along the top of the plot, aligned to the time\n * axis. Their dates must fall within the plotted day.\n */\n weather?: SolarForecastWeatherPoint[]\n /** Sunrise time, drawn as a labelled vertical marker on the plot. */\n sunrise?: Date\n /** Sunset time, drawn as a labelled vertical marker on the plot. */\n sunset?: Date\n /** Label formatter for the sunrise/sunset markers. Defaults to `formatTime`. */\n formatMarkerTime?: (date: Date) => string\n curve?: LineChartCurve\n height?: number\n className?: string\n zoomable?: boolean\n zoomResetLabel?: string\n zoomDomain?: [Date, Date] | null\n onZoomDomainChange?: (domain: [Date, Date] | null) => void\n}\n\n/**\n * Responsive line plot of measured production (solid) against a forecast\n * (dashed) over a day. Optionally overlays hourly weather icons and\n * sunrise/sunset markers, all pinned to the same time axis. Sizes itself to its\n * container; compose a title and any summary around it.\n */\nexport function SolarForecastChart({\n produced,\n forecast,\n producedLabel = 'Produced',\n forecastLabel = 'Forecast',\n formatValue = defaultFormatValue,\n yAxisUnit = 'kW',\n formatTime = defaultFormatTime,\n formatTooltipTime,\n weather,\n sunrise,\n sunset,\n formatMarkerTime,\n curve = 'monotone',\n height = DEFAULT_HEIGHT,\n className,\n zoomable,\n zoomResetLabel,\n zoomDomain,\n onZoomDomainChange,\n}: SolarForecastChartProps): JSX.Element {\n const containerRef = useRef<HTMLDivElement>(null)\n const [width, setWidth] = useState(0)\n\n useEffect(() => {\n const el = containerRef.current\n if (!el) return\n const ro = new ResizeObserver((entries) => {\n const entry = entries[0]\n if (entry) setWidth(entry.contentRect.width)\n })\n ro.observe(el)\n return () => ro.disconnect()\n }, [])\n\n const hasWeather = weather != null && weather.length > 0\n const margin = {\n ...BASE_MARGIN,\n top: hasWeather ? BASE_MARGIN.top + WEATHER_ROW_HEIGHT : BASE_MARGIN.top,\n }\n const formatMarker = formatMarkerTime ?? formatTooltipTime ?? formatTime\n\n const topContent = hasWeather\n ? weather.map((point, i) => {\n const WeatherGlyph = point.icon\n return {\n key: `weather-${point.date.valueOf()}-${i}`,\n date: point.date,\n content: (\n <WeatherGlyph className=\"text-gray-light [--spark-icon-size:18px]\" />\n ),\n }\n })\n : undefined\n\n const referenceLines = [\n sunrise && { key: 'sunrise', date: sunrise, label: formatMarker(sunrise) },\n sunset && { key: 'sunset', date: sunset, label: formatMarker(sunset) },\n ].filter((x): x is { key: string; date: Date; label: string } => Boolean(x))\n\n return (\n <div ref={containerRef} className={cn('w-full', className)}>\n {width > 0 && (\n <LineChart\n width={width}\n height={height}\n margin={margin}\n curve={curve}\n series={[\n { id: 'produced', data: produced, label: producedLabel },\n {\n id: 'forecast',\n data: forecast,\n label: forecastLabel,\n dashed: true,\n },\n ]}\n showGrid\n xTickCount={6}\n yTickCount={4}\n yAxisUnit={yAxisUnit}\n formatDate={formatTime}\n formatTooltipDate={formatTooltipTime ?? formatTime}\n formatValue={formatValue}\n referenceLines={\n referenceLines.length > 0 ? referenceLines : undefined\n }\n topContent={topContent}\n zoomable={zoomable}\n zoomResetLabel={zoomResetLabel}\n zoomDomain={zoomDomain}\n onZoomDomainChange={onZoomDomainChange}\n />\n )}\n </div>\n )\n}\n\nexport default SolarForecastChart\n"],"mappings":";;;;;;;;;;;;AAWA,MAAM,iBAAiB;AAGvB,MAAM,cAAc;CAAE,KAAK;CAAG,OAAO;CAAG,QAAQ;CAAI,MAAM;AAAG;;AAE7D,MAAM,qBAAqB;AAE3B,SAAS,mBAAmB,OAAuB;CACjD,OAAO,GAAGA,qBAAAA,iBAAiB,OAAO,KAAK;AACzC;AAEA,SAAS,kBAAkB,MAAoB;CAC7C,OAAO,KAAK,SAAS,EAAE,SAAS,EAAE,SAAS,GAAG,GAAG;AACnD;;;;;;;AAkDA,SAAgB,mBAAmB,EACjC,UACA,UACA,gBAAgB,YAChB,gBAAgB,YAChB,cAAc,oBACd,YAAY,MACZ,aAAa,mBACb,mBACA,SACA,SACA,QACA,kBACA,QAAQ,YACR,SAAS,gBACT,WACA,UACA,gBACA,YACA,sBACuC;CACvC,MAAM,gBAAA,GAAA,MAAA,QAAsC,IAAI;CAChD,MAAM,CAAC,OAAO,aAAA,GAAA,MAAA,UAAqB,CAAC;CAEpC,CAAA,GAAA,MAAA,iBAAgB;EACd,MAAM,KAAK,aAAa;EACxB,IAAI,CAAC,IAAI;EACT,MAAM,KAAK,IAAI,gBAAgB,YAAY;GACzC,MAAM,QAAQ,QAAQ;GACtB,IAAI,OAAO,SAAS,MAAM,YAAY,KAAK;EAC7C,CAAC;EACD,GAAG,QAAQ,EAAE;EACb,aAAa,GAAG,WAAW;CAC7B,GAAG,CAAC,CAAC;CAEL,MAAM,aAAa,WAAW,QAAQ,QAAQ,SAAS;CACvD,MAAM,SAAS;EACb,GAAG;EACH,KAAK,aAAa,YAAY,MAAM,qBAAqB,YAAY;CACvE;CACA,MAAM,eAAe,oBAAoB,qBAAqB;CAE9D,MAAM,aAAa,aACf,QAAQ,KAAK,OAAO,MAAM;EACxB,MAAM,eAAe,MAAM;EAC3B,OAAO;GACL,KAAK,WAAW,MAAM,KAAK,QAAQ,EAAE,GAAG;GACxC,MAAM,MAAM;GACZ,SACE,iBAAA,GAAA,kBAAA,KAAC,cAAD,EAAc,WAAU,2CAA4C,CAAA;EAExE;CACF,CAAC,IACD,KAAA;CAEJ,MAAM,iBAAiB,CACrB,WAAW;EAAE,KAAK;EAAW,MAAM;EAAS,OAAO,aAAa,OAAO;CAAE,GACzE,UAAU;EAAE,KAAK;EAAU,MAAM;EAAQ,OAAO,aAAa,MAAM;CAAE,CACvE,EAAE,QAAQ,MAAuD,QAAQ,CAAC,CAAC;CAE3E,OACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;EAAK,KAAK;EAAc,YAAA,GAAA,OAAA,IAAc,UAAU,SAAS;YACtD,QAAQ,KACP,iBAAA,GAAA,kBAAA,KAACC,8BAAAA,WAAD;GACS;GACC;GACA;GACD;GACP,QAAQ,CACN;IAAE,IAAI;IAAY,MAAM;IAAU,OAAO;GAAc,GACvD;IACE,IAAI;IACJ,MAAM;IACN,OAAO;IACP,QAAQ;GACV,CACF;GACA,UAAA;GACA,YAAY;GACZ,YAAY;GACD;GACX,YAAY;GACZ,mBAAmB,qBAAqB;GAC3B;GACb,gBACE,eAAe,SAAS,IAAI,iBAAiB,KAAA;GAEnC;GACF;GACM;GACJ;GACQ;EACrB,CAAA;CAEA,CAAA;AAET"}
@@ -1,77 +0,0 @@
1
- "use client";
2
-
3
- import { LineChartCurve, LineChartDatum } from "./line-chart.cjs";
4
- import { JSX, ReactNode } from "react";
5
- import { SparkIcon } from "@epilot/spark-icons";
6
-
7
- //#region src/components/solar-forecast-chart.d.ts
8
- interface SolarForecastWeatherPoint {
9
- date: Date;
10
- icon: SparkIcon;
11
- }
12
- interface SolarForecastChartProps {
13
- /** Measured production, drawn as the solid line. */
14
- produced: LineChartDatum[];
15
- /** Predicted production, drawn as the dashed line. */
16
- forecast: LineChartDatum[];
17
- /** Tooltip label for the produced series. */
18
- producedLabel?: ReactNode;
19
- /** Tooltip label for the forecast series. */
20
- forecastLabel?: ReactNode;
21
- /** Tooltip value formatter. Defaults to one-decimal kW (power). */
22
- formatValue?: (value: number) => string;
23
- /** Unit shown once atop the y-axis; ticks render as plain numbers. Defaults to "kW". */
24
- yAxisUnit?: string;
25
- /** X-axis tick formatter. Defaults to the zero-padded hour. */
26
- formatTime?: (date: Date) => string;
27
- /** Tooltip time formatter. Defaults to `formatTime`. */
28
- formatTooltipTime?: (date: Date) => string;
29
- /**
30
- * Hourly weather icons drawn along the top of the plot, aligned to the time
31
- * axis. Their dates must fall within the plotted day.
32
- */
33
- weather?: SolarForecastWeatherPoint[];
34
- /** Sunrise time, drawn as a labelled vertical marker on the plot. */
35
- sunrise?: Date;
36
- /** Sunset time, drawn as a labelled vertical marker on the plot. */
37
- sunset?: Date;
38
- /** Label formatter for the sunrise/sunset markers. Defaults to `formatTime`. */
39
- formatMarkerTime?: (date: Date) => string;
40
- curve?: LineChartCurve;
41
- height?: number;
42
- className?: string;
43
- zoomable?: boolean;
44
- zoomResetLabel?: string;
45
- zoomDomain?: [Date, Date] | null;
46
- onZoomDomainChange?: (domain: [Date, Date] | null) => void;
47
- }
48
- /**
49
- * Responsive line plot of measured production (solid) against a forecast
50
- * (dashed) over a day. Optionally overlays hourly weather icons and
51
- * sunrise/sunset markers, all pinned to the same time axis. Sizes itself to its
52
- * container; compose a title and any summary around it.
53
- */
54
- declare function SolarForecastChart({
55
- produced,
56
- forecast,
57
- producedLabel,
58
- forecastLabel,
59
- formatValue,
60
- yAxisUnit,
61
- formatTime,
62
- formatTooltipTime,
63
- weather,
64
- sunrise,
65
- sunset,
66
- formatMarkerTime,
67
- curve,
68
- height,
69
- className,
70
- zoomable,
71
- zoomResetLabel,
72
- zoomDomain,
73
- onZoomDomainChange
74
- }: SolarForecastChartProps): JSX.Element;
75
- //#endregion
76
- export { SolarForecastChart, SolarForecastChart as default, SolarForecastChartProps, SolarForecastWeatherPoint };
77
- //# sourceMappingURL=solar-forecast-chart.d.cts.map
@@ -1,77 +0,0 @@
1
- "use client";
2
-
3
- import { LineChartCurve, LineChartDatum } from "./line-chart.js";
4
- import { JSX, ReactNode } from "react";
5
- import { SparkIcon } from "@epilot/spark-icons";
6
-
7
- //#region src/components/solar-forecast-chart.d.ts
8
- interface SolarForecastWeatherPoint {
9
- date: Date;
10
- icon: SparkIcon;
11
- }
12
- interface SolarForecastChartProps {
13
- /** Measured production, drawn as the solid line. */
14
- produced: LineChartDatum[];
15
- /** Predicted production, drawn as the dashed line. */
16
- forecast: LineChartDatum[];
17
- /** Tooltip label for the produced series. */
18
- producedLabel?: ReactNode;
19
- /** Tooltip label for the forecast series. */
20
- forecastLabel?: ReactNode;
21
- /** Tooltip value formatter. Defaults to one-decimal kW (power). */
22
- formatValue?: (value: number) => string;
23
- /** Unit shown once atop the y-axis; ticks render as plain numbers. Defaults to "kW". */
24
- yAxisUnit?: string;
25
- /** X-axis tick formatter. Defaults to the zero-padded hour. */
26
- formatTime?: (date: Date) => string;
27
- /** Tooltip time formatter. Defaults to `formatTime`. */
28
- formatTooltipTime?: (date: Date) => string;
29
- /**
30
- * Hourly weather icons drawn along the top of the plot, aligned to the time
31
- * axis. Their dates must fall within the plotted day.
32
- */
33
- weather?: SolarForecastWeatherPoint[];
34
- /** Sunrise time, drawn as a labelled vertical marker on the plot. */
35
- sunrise?: Date;
36
- /** Sunset time, drawn as a labelled vertical marker on the plot. */
37
- sunset?: Date;
38
- /** Label formatter for the sunrise/sunset markers. Defaults to `formatTime`. */
39
- formatMarkerTime?: (date: Date) => string;
40
- curve?: LineChartCurve;
41
- height?: number;
42
- className?: string;
43
- zoomable?: boolean;
44
- zoomResetLabel?: string;
45
- zoomDomain?: [Date, Date] | null;
46
- onZoomDomainChange?: (domain: [Date, Date] | null) => void;
47
- }
48
- /**
49
- * Responsive line plot of measured production (solid) against a forecast
50
- * (dashed) over a day. Optionally overlays hourly weather icons and
51
- * sunrise/sunset markers, all pinned to the same time axis. Sizes itself to its
52
- * container; compose a title and any summary around it.
53
- */
54
- declare function SolarForecastChart({
55
- produced,
56
- forecast,
57
- producedLabel,
58
- forecastLabel,
59
- formatValue,
60
- yAxisUnit,
61
- formatTime,
62
- formatTooltipTime,
63
- weather,
64
- sunrise,
65
- sunset,
66
- formatMarkerTime,
67
- curve,
68
- height,
69
- className,
70
- zoomable,
71
- zoomResetLabel,
72
- zoomDomain,
73
- onZoomDomainChange
74
- }: SolarForecastChartProps): JSX.Element;
75
- //#endregion
76
- export { SolarForecastChart, SolarForecastChart as default, SolarForecastChartProps, SolarForecastWeatherPoint };
77
- //# sourceMappingURL=solar-forecast-chart.d.ts.map
@@ -1,103 +0,0 @@
1
- "use client";
2
- import "../utils/chars.js";
3
- import { oneDecimalFormat } from "../utils/format.js";
4
- import { cn } from "../utils/cn.js";
5
- import { LineChart } from "./line-chart.js";
6
- import { useEffect, useRef, useState } from "react";
7
- import { jsx } from "react/jsx-runtime";
8
- //#region src/components/solar-forecast-chart.tsx
9
- const DEFAULT_HEIGHT = 220;
10
- const BASE_MARGIN = {
11
- top: 8,
12
- right: 8,
13
- bottom: 28,
14
- left: 34
15
- };
16
- /** Extra headroom for the weather icon row pinned above the plot. */
17
- const WEATHER_ROW_HEIGHT = 24;
18
- function defaultFormatValue(value) {
19
- return `${oneDecimalFormat.format(value)} kW`;
20
- }
21
- function defaultFormatTime(date) {
22
- return date.getHours().toString().padStart(2, "0");
23
- }
24
- /**
25
- * Responsive line plot of measured production (solid) against a forecast
26
- * (dashed) over a day. Optionally overlays hourly weather icons and
27
- * sunrise/sunset markers, all pinned to the same time axis. Sizes itself to its
28
- * container; compose a title and any summary around it.
29
- */
30
- function SolarForecastChart({ produced, forecast, producedLabel = "Produced", forecastLabel = "Forecast", formatValue = defaultFormatValue, yAxisUnit = "kW", formatTime = defaultFormatTime, formatTooltipTime, weather, sunrise, sunset, formatMarkerTime, curve = "monotone", height = DEFAULT_HEIGHT, className, zoomable, zoomResetLabel, zoomDomain, onZoomDomainChange }) {
31
- const containerRef = useRef(null);
32
- const [width, setWidth] = useState(0);
33
- useEffect(() => {
34
- const el = containerRef.current;
35
- if (!el) return;
36
- const ro = new ResizeObserver((entries) => {
37
- const entry = entries[0];
38
- if (entry) setWidth(entry.contentRect.width);
39
- });
40
- ro.observe(el);
41
- return () => ro.disconnect();
42
- }, []);
43
- const hasWeather = weather != null && weather.length > 0;
44
- const margin = {
45
- ...BASE_MARGIN,
46
- top: hasWeather ? BASE_MARGIN.top + WEATHER_ROW_HEIGHT : BASE_MARGIN.top
47
- };
48
- const formatMarker = formatMarkerTime ?? formatTooltipTime ?? formatTime;
49
- const topContent = hasWeather ? weather.map((point, i) => {
50
- const WeatherGlyph = point.icon;
51
- return {
52
- key: `weather-${point.date.valueOf()}-${i}`,
53
- date: point.date,
54
- content: /* @__PURE__ */ jsx(WeatherGlyph, { className: "text-gray-light [--spark-icon-size:18px]" })
55
- };
56
- }) : void 0;
57
- const referenceLines = [sunrise && {
58
- key: "sunrise",
59
- date: sunrise,
60
- label: formatMarker(sunrise)
61
- }, sunset && {
62
- key: "sunset",
63
- date: sunset,
64
- label: formatMarker(sunset)
65
- }].filter((x) => Boolean(x));
66
- return /* @__PURE__ */ jsx("div", {
67
- ref: containerRef,
68
- className: cn("w-full", className),
69
- children: width > 0 && /* @__PURE__ */ jsx(LineChart, {
70
- width,
71
- height,
72
- margin,
73
- curve,
74
- series: [{
75
- id: "produced",
76
- data: produced,
77
- label: producedLabel
78
- }, {
79
- id: "forecast",
80
- data: forecast,
81
- label: forecastLabel,
82
- dashed: true
83
- }],
84
- showGrid: true,
85
- xTickCount: 6,
86
- yTickCount: 4,
87
- yAxisUnit,
88
- formatDate: formatTime,
89
- formatTooltipDate: formatTooltipTime ?? formatTime,
90
- formatValue,
91
- referenceLines: referenceLines.length > 0 ? referenceLines : void 0,
92
- topContent,
93
- zoomable,
94
- zoomResetLabel,
95
- zoomDomain,
96
- onZoomDomainChange
97
- })
98
- });
99
- }
100
- //#endregion
101
- export { SolarForecastChart, SolarForecastChart as default };
102
-
103
- //# sourceMappingURL=solar-forecast-chart.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"solar-forecast-chart.js","names":[],"sources":["../../src/components/solar-forecast-chart.tsx"],"sourcesContent":["import type { SparkIcon } from '@epilot/spark-icons'\nimport { type JSX, type ReactNode, useEffect, useRef, useState } from 'react'\nimport { NARROW_NBSP } from '../utils/chars'\nimport { cn } from '../utils/cn'\nimport { oneDecimalFormat } from '../utils/format'\nimport {\n LineChart,\n type LineChartCurve,\n type LineChartDatum,\n} from './line-chart'\n\nconst DEFAULT_HEIGHT = 220\n// `left` leaves room for the y-axis tick labels + unit (matches the 34px gutter\n// used by BarChart / PowerHistoryChart).\nconst BASE_MARGIN = { top: 8, right: 8, bottom: 28, left: 34 }\n/** Extra headroom for the weather icon row pinned above the plot. */\nconst WEATHER_ROW_HEIGHT = 24\n\nfunction defaultFormatValue(value: number): string {\n return `${oneDecimalFormat.format(value)}${NARROW_NBSP}kW`\n}\n\nfunction defaultFormatTime(date: Date): string {\n return date.getHours().toString().padStart(2, '0')\n}\n\nexport interface SolarForecastWeatherPoint {\n date: Date\n icon: SparkIcon\n}\n\nexport interface SolarForecastChartProps {\n /** Measured production, drawn as the solid line. */\n produced: LineChartDatum[]\n /** Predicted production, drawn as the dashed line. */\n forecast: LineChartDatum[]\n /** Tooltip label for the produced series. */\n producedLabel?: ReactNode\n /** Tooltip label for the forecast series. */\n forecastLabel?: ReactNode\n /** Tooltip value formatter. Defaults to one-decimal kW (power). */\n formatValue?: (value: number) => string\n /** Unit shown once atop the y-axis; ticks render as plain numbers. Defaults to \"kW\". */\n yAxisUnit?: string\n /** X-axis tick formatter. Defaults to the zero-padded hour. */\n formatTime?: (date: Date) => string\n /** Tooltip time formatter. Defaults to `formatTime`. */\n formatTooltipTime?: (date: Date) => string\n /**\n * Hourly weather icons drawn along the top of the plot, aligned to the time\n * axis. Their dates must fall within the plotted day.\n */\n weather?: SolarForecastWeatherPoint[]\n /** Sunrise time, drawn as a labelled vertical marker on the plot. */\n sunrise?: Date\n /** Sunset time, drawn as a labelled vertical marker on the plot. */\n sunset?: Date\n /** Label formatter for the sunrise/sunset markers. Defaults to `formatTime`. */\n formatMarkerTime?: (date: Date) => string\n curve?: LineChartCurve\n height?: number\n className?: string\n zoomable?: boolean\n zoomResetLabel?: string\n zoomDomain?: [Date, Date] | null\n onZoomDomainChange?: (domain: [Date, Date] | null) => void\n}\n\n/**\n * Responsive line plot of measured production (solid) against a forecast\n * (dashed) over a day. Optionally overlays hourly weather icons and\n * sunrise/sunset markers, all pinned to the same time axis. Sizes itself to its\n * container; compose a title and any summary around it.\n */\nexport function SolarForecastChart({\n produced,\n forecast,\n producedLabel = 'Produced',\n forecastLabel = 'Forecast',\n formatValue = defaultFormatValue,\n yAxisUnit = 'kW',\n formatTime = defaultFormatTime,\n formatTooltipTime,\n weather,\n sunrise,\n sunset,\n formatMarkerTime,\n curve = 'monotone',\n height = DEFAULT_HEIGHT,\n className,\n zoomable,\n zoomResetLabel,\n zoomDomain,\n onZoomDomainChange,\n}: SolarForecastChartProps): JSX.Element {\n const containerRef = useRef<HTMLDivElement>(null)\n const [width, setWidth] = useState(0)\n\n useEffect(() => {\n const el = containerRef.current\n if (!el) return\n const ro = new ResizeObserver((entries) => {\n const entry = entries[0]\n if (entry) setWidth(entry.contentRect.width)\n })\n ro.observe(el)\n return () => ro.disconnect()\n }, [])\n\n const hasWeather = weather != null && weather.length > 0\n const margin = {\n ...BASE_MARGIN,\n top: hasWeather ? BASE_MARGIN.top + WEATHER_ROW_HEIGHT : BASE_MARGIN.top,\n }\n const formatMarker = formatMarkerTime ?? formatTooltipTime ?? formatTime\n\n const topContent = hasWeather\n ? weather.map((point, i) => {\n const WeatherGlyph = point.icon\n return {\n key: `weather-${point.date.valueOf()}-${i}`,\n date: point.date,\n content: (\n <WeatherGlyph className=\"text-gray-light [--spark-icon-size:18px]\" />\n ),\n }\n })\n : undefined\n\n const referenceLines = [\n sunrise && { key: 'sunrise', date: sunrise, label: formatMarker(sunrise) },\n sunset && { key: 'sunset', date: sunset, label: formatMarker(sunset) },\n ].filter((x): x is { key: string; date: Date; label: string } => Boolean(x))\n\n return (\n <div ref={containerRef} className={cn('w-full', className)}>\n {width > 0 && (\n <LineChart\n width={width}\n height={height}\n margin={margin}\n curve={curve}\n series={[\n { id: 'produced', data: produced, label: producedLabel },\n {\n id: 'forecast',\n data: forecast,\n label: forecastLabel,\n dashed: true,\n },\n ]}\n showGrid\n xTickCount={6}\n yTickCount={4}\n yAxisUnit={yAxisUnit}\n formatDate={formatTime}\n formatTooltipDate={formatTooltipTime ?? formatTime}\n formatValue={formatValue}\n referenceLines={\n referenceLines.length > 0 ? referenceLines : undefined\n }\n topContent={topContent}\n zoomable={zoomable}\n zoomResetLabel={zoomResetLabel}\n zoomDomain={zoomDomain}\n onZoomDomainChange={onZoomDomainChange}\n />\n )}\n </div>\n )\n}\n\nexport default SolarForecastChart\n"],"mappings":";;;;;;;;AAWA,MAAM,iBAAiB;AAGvB,MAAM,cAAc;CAAE,KAAK;CAAG,OAAO;CAAG,QAAQ;CAAI,MAAM;AAAG;;AAE7D,MAAM,qBAAqB;AAE3B,SAAS,mBAAmB,OAAuB;CACjD,OAAO,GAAG,iBAAiB,OAAO,KAAK;AACzC;AAEA,SAAS,kBAAkB,MAAoB;CAC7C,OAAO,KAAK,SAAS,EAAE,SAAS,EAAE,SAAS,GAAG,GAAG;AACnD;;;;;;;AAkDA,SAAgB,mBAAmB,EACjC,UACA,UACA,gBAAgB,YAChB,gBAAgB,YAChB,cAAc,oBACd,YAAY,MACZ,aAAa,mBACb,mBACA,SACA,SACA,QACA,kBACA,QAAQ,YACR,SAAS,gBACT,WACA,UACA,gBACA,YACA,sBACuC;CACvC,MAAM,eAAe,OAAuB,IAAI;CAChD,MAAM,CAAC,OAAO,YAAY,SAAS,CAAC;CAEpC,gBAAgB;EACd,MAAM,KAAK,aAAa;EACxB,IAAI,CAAC,IAAI;EACT,MAAM,KAAK,IAAI,gBAAgB,YAAY;GACzC,MAAM,QAAQ,QAAQ;GACtB,IAAI,OAAO,SAAS,MAAM,YAAY,KAAK;EAC7C,CAAC;EACD,GAAG,QAAQ,EAAE;EACb,aAAa,GAAG,WAAW;CAC7B,GAAG,CAAC,CAAC;CAEL,MAAM,aAAa,WAAW,QAAQ,QAAQ,SAAS;CACvD,MAAM,SAAS;EACb,GAAG;EACH,KAAK,aAAa,YAAY,MAAM,qBAAqB,YAAY;CACvE;CACA,MAAM,eAAe,oBAAoB,qBAAqB;CAE9D,MAAM,aAAa,aACf,QAAQ,KAAK,OAAO,MAAM;EACxB,MAAM,eAAe,MAAM;EAC3B,OAAO;GACL,KAAK,WAAW,MAAM,KAAK,QAAQ,EAAE,GAAG;GACxC,MAAM,MAAM;GACZ,SACE,oBAAC,cAAD,EAAc,WAAU,2CAA4C,CAAA;EAExE;CACF,CAAC,IACD,KAAA;CAEJ,MAAM,iBAAiB,CACrB,WAAW;EAAE,KAAK;EAAW,MAAM;EAAS,OAAO,aAAa,OAAO;CAAE,GACzE,UAAU;EAAE,KAAK;EAAU,MAAM;EAAQ,OAAO,aAAa,MAAM;CAAE,CACvE,EAAE,QAAQ,MAAuD,QAAQ,CAAC,CAAC;CAE3E,OACE,oBAAC,OAAD;EAAK,KAAK;EAAc,WAAW,GAAG,UAAU,SAAS;YACtD,QAAQ,KACP,oBAAC,WAAD;GACS;GACC;GACA;GACD;GACP,QAAQ,CACN;IAAE,IAAI;IAAY,MAAM;IAAU,OAAO;GAAc,GACvD;IACE,IAAI;IACJ,MAAM;IACN,OAAO;IACP,QAAQ;GACV,CACF;GACA,UAAA;GACA,YAAY;GACZ,YAAY;GACD;GACX,YAAY;GACZ,mBAAmB,qBAAqB;GAC3B;GACb,gBACE,eAAe,SAAS,IAAI,iBAAiB,KAAA;GAEnC;GACF;GACM;GACJ;GACQ;EACrB,CAAA;CAEA,CAAA;AAET"}
@@ -1,14 +0,0 @@
1
- "use client";
2
-
3
- import { Format, NumberFlowProps, NumberFlowProps as NumberFlowProps$1 } from "@number-flow/react";
4
-
5
- //#region src/components/number-flow.d.ts
6
- declare function NumberFlow({
7
- locales,
8
- prefix,
9
- suffix,
10
- ...props
11
- }: NumberFlowProps): import("react/jsx-runtime").JSX.Element;
12
- //#endregion
13
- export { NumberFlow as n, NumberFlowProps$1 as r, Format as t };
14
- //# sourceMappingURL=number-flow-Bch81ixZ.d.cts.map
@@ -1,14 +0,0 @@
1
- "use client";
2
-
3
- import { Format, NumberFlowProps, NumberFlowProps as NumberFlowProps$1 } from "@number-flow/react";
4
-
5
- //#region src/components/number-flow.d.ts
6
- declare function NumberFlow({
7
- locales,
8
- prefix,
9
- suffix,
10
- ...props
11
- }: NumberFlowProps): import("react/jsx-runtime").JSX.Element;
12
- //#endregion
13
- export { NumberFlow as n, NumberFlowProps$1 as r, Format as t };
14
- //# sourceMappingURL=number-flow-Bch81ixZ.d.ts.map
@@ -1,72 +0,0 @@
1
- "use client";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- //#region src/utils/build-sankey-nodes.ts
4
- function buildSankeyNodes({ solarPower, batteryPower, gridPower, floorShares, deviceSharesByFloor }) {
5
- const solar = Math.max(0, solarPower);
6
- const gridImport = Math.max(0, gridPower);
7
- const gridExport = Math.max(0, -gridPower);
8
- const batteryDischarge = Math.max(0, batteryPower);
9
- const batteryCharge = Math.max(0, -batteryPower);
10
- const solarToBattery = Math.min(solar, batteryCharge);
11
- const gridToBattery = Math.min(gridImport, batteryCharge - solarToBattery);
12
- const solarToFeedIn = Math.min(solar - solarToBattery, gridExport);
13
- const batteryToFeedIn = Math.min(batteryDischarge, gridExport - solarToFeedIn);
14
- const links = [
15
- {
16
- source: "grid",
17
- target: "home",
18
- value: gridImport - gridToBattery
19
- },
20
- {
21
- source: "solar",
22
- target: "home",
23
- value: solar - solarToBattery - solarToFeedIn
24
- },
25
- {
26
- source: "battery",
27
- target: "home",
28
- value: batteryDischarge - batteryToFeedIn
29
- },
30
- {
31
- source: "solar",
32
- target: "battery",
33
- value: solarToBattery
34
- },
35
- {
36
- source: "grid",
37
- target: "battery",
38
- value: gridToBattery
39
- },
40
- {
41
- source: "solar",
42
- target: "gridFeedIn",
43
- value: solarToFeedIn
44
- },
45
- {
46
- source: "battery",
47
- target: "gridFeedIn",
48
- value: batteryToFeedIn
49
- }
50
- ];
51
- if (!floorShares) return links;
52
- const homeWatts = solar - solarToBattery - solarToFeedIn + (gridImport - gridToBattery) + (batteryDischarge - batteryToFeedIn);
53
- for (const [floorId, share] of Object.entries(floorShares)) {
54
- const floorWatts = homeWatts * share;
55
- links.push({
56
- source: "home",
57
- target: floorId,
58
- value: floorWatts
59
- });
60
- const deviceShares = deviceSharesByFloor?.[floorId] ?? {};
61
- for (const [deviceId, deviceShare] of Object.entries(deviceShares)) links.push({
62
- source: floorId,
63
- target: deviceId,
64
- value: floorWatts * deviceShare
65
- });
66
- }
67
- return links;
68
- }
69
- //#endregion
70
- exports.buildSankeyNodes = buildSankeyNodes;
71
-
72
- //# sourceMappingURL=build-sankey-nodes.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"build-sankey-nodes.cjs","names":[],"sources":["../../src/utils/build-sankey-nodes.ts"],"sourcesContent":["import type { SankeyChartLink } from '../components/sankey-chart'\n\ntype SankeyNodesArgs = {\n solarPower: number\n /**\n * Signed storage power: positive = discharging into the home, negative =\n * charging from solar/grid. Charging power is routed into the `battery`\n * node so it isn't mistakenly attributed to home consumption.\n */\n batteryPower: number\n gridPower: number\n floorShares?: Record<string, number>\n deviceSharesByFloor?: Record<string, Record<string, number>>\n}\n\nfunction buildSankeyNodes({\n solarPower,\n batteryPower,\n gridPower,\n floorShares,\n deviceSharesByFloor,\n}: SankeyNodesArgs): SankeyChartLink[] {\n const solar = Math.max(0, solarPower)\n const gridImport = Math.max(0, gridPower)\n const gridExport = Math.max(0, -gridPower)\n const batteryDischarge = Math.max(0, batteryPower)\n const batteryCharge = Math.max(0, -batteryPower)\n\n // Charge the battery from solar surplus first, then from the grid. Routing\n // the charge flow into the `battery` node (a sink while charging) keeps it\n // out of the `home` node, which should reflect actual consumption only.\n const solarToBattery = Math.min(solar, batteryCharge)\n const gridToBattery = Math.min(gridImport, batteryCharge - solarToBattery)\n\n // Grid feed-in (export). Cover it from the solar surplus first, then fall\n // back to battery discharge. Like battery charging, this must not land in the\n // `home` node — it's power leaving the house, not consumption.\n const solarToFeedIn = Math.min(solar - solarToBattery, gridExport)\n const batteryToFeedIn = Math.min(batteryDischarge, gridExport - solarToFeedIn)\n\n const links: SankeyChartLink[] = [\n { source: 'grid', target: 'home', value: gridImport - gridToBattery },\n {\n source: 'solar',\n target: 'home',\n value: solar - solarToBattery - solarToFeedIn,\n },\n {\n source: 'battery',\n target: 'home',\n value: batteryDischarge - batteryToFeedIn,\n },\n { source: 'solar', target: 'battery', value: solarToBattery },\n { source: 'grid', target: 'battery', value: gridToBattery },\n { source: 'solar', target: 'gridFeedIn', value: solarToFeedIn },\n { source: 'battery', target: 'gridFeedIn', value: batteryToFeedIn },\n ]\n\n if (!floorShares) return links\n\n const homeWatts =\n solar -\n solarToBattery -\n solarToFeedIn +\n (gridImport - gridToBattery) +\n (batteryDischarge - batteryToFeedIn)\n\n for (const [floorId, share] of Object.entries(floorShares)) {\n const floorWatts = homeWatts * share\n links.push({ source: 'home', target: floorId, value: floorWatts })\n\n const deviceShares = deviceSharesByFloor?.[floorId] ?? {}\n for (const [deviceId, deviceShare] of Object.entries(deviceShares)) {\n links.push({\n source: floorId,\n target: deviceId,\n value: floorWatts * deviceShare,\n })\n }\n }\n\n return links\n}\n\nexport { buildSankeyNodes }\n"],"mappings":";;;AAeA,SAAS,iBAAiB,EACxB,YACA,cACA,WACA,aACA,uBACqC;CACrC,MAAM,QAAQ,KAAK,IAAI,GAAG,UAAU;CACpC,MAAM,aAAa,KAAK,IAAI,GAAG,SAAS;CACxC,MAAM,aAAa,KAAK,IAAI,GAAG,CAAC,SAAS;CACzC,MAAM,mBAAmB,KAAK,IAAI,GAAG,YAAY;CACjD,MAAM,gBAAgB,KAAK,IAAI,GAAG,CAAC,YAAY;CAK/C,MAAM,iBAAiB,KAAK,IAAI,OAAO,aAAa;CACpD,MAAM,gBAAgB,KAAK,IAAI,YAAY,gBAAgB,cAAc;CAKzE,MAAM,gBAAgB,KAAK,IAAI,QAAQ,gBAAgB,UAAU;CACjE,MAAM,kBAAkB,KAAK,IAAI,kBAAkB,aAAa,aAAa;CAE7E,MAAM,QAA2B;EAC/B;GAAE,QAAQ;GAAQ,QAAQ;GAAQ,OAAO,aAAa;EAAc;EACpE;GACE,QAAQ;GACR,QAAQ;GACR,OAAO,QAAQ,iBAAiB;EAClC;EACA;GACE,QAAQ;GACR,QAAQ;GACR,OAAO,mBAAmB;EAC5B;EACA;GAAE,QAAQ;GAAS,QAAQ;GAAW,OAAO;EAAe;EAC5D;GAAE,QAAQ;GAAQ,QAAQ;GAAW,OAAO;EAAc;EAC1D;GAAE,QAAQ;GAAS,QAAQ;GAAc,OAAO;EAAc;EAC9D;GAAE,QAAQ;GAAW,QAAQ;GAAc,OAAO;EAAgB;CACpE;CAEA,IAAI,CAAC,aAAa,OAAO;CAEzB,MAAM,YACJ,QACA,iBACA,iBACC,aAAa,kBACb,mBAAmB;CAEtB,KAAK,MAAM,CAAC,SAAS,UAAU,OAAO,QAAQ,WAAW,GAAG;EAC1D,MAAM,aAAa,YAAY;EAC/B,MAAM,KAAK;GAAE,QAAQ;GAAQ,QAAQ;GAAS,OAAO;EAAW,CAAC;EAEjE,MAAM,eAAe,sBAAsB,YAAY,CAAC;EACxD,KAAK,MAAM,CAAC,UAAU,gBAAgB,OAAO,QAAQ,YAAY,GAC/D,MAAM,KAAK;GACT,QAAQ;GACR,QAAQ;GACR,OAAO,aAAa;EACtB,CAAC;CAEL;CAEA,OAAO;AACT"}
@@ -1,27 +0,0 @@
1
- "use client";
2
-
3
- import { SankeyChartLink } from "../components/sankey-chart.cjs";
4
-
5
- //#region src/utils/build-sankey-nodes.d.ts
6
- type SankeyNodesArgs = {
7
- solarPower: number;
8
- /**
9
- * Signed storage power: positive = discharging into the home, negative =
10
- * charging from solar/grid. Charging power is routed into the `battery`
11
- * node so it isn't mistakenly attributed to home consumption.
12
- */
13
- batteryPower: number;
14
- gridPower: number;
15
- floorShares?: Record<string, number>;
16
- deviceSharesByFloor?: Record<string, Record<string, number>>;
17
- };
18
- declare function buildSankeyNodes({
19
- solarPower,
20
- batteryPower,
21
- gridPower,
22
- floorShares,
23
- deviceSharesByFloor
24
- }: SankeyNodesArgs): SankeyChartLink[];
25
- //#endregion
26
- export { buildSankeyNodes };
27
- //# sourceMappingURL=build-sankey-nodes.d.cts.map
@@ -1,27 +0,0 @@
1
- "use client";
2
-
3
- import { SankeyChartLink } from "../components/sankey-chart.js";
4
-
5
- //#region src/utils/build-sankey-nodes.d.ts
6
- type SankeyNodesArgs = {
7
- solarPower: number;
8
- /**
9
- * Signed storage power: positive = discharging into the home, negative =
10
- * charging from solar/grid. Charging power is routed into the `battery`
11
- * node so it isn't mistakenly attributed to home consumption.
12
- */
13
- batteryPower: number;
14
- gridPower: number;
15
- floorShares?: Record<string, number>;
16
- deviceSharesByFloor?: Record<string, Record<string, number>>;
17
- };
18
- declare function buildSankeyNodes({
19
- solarPower,
20
- batteryPower,
21
- gridPower,
22
- floorShares,
23
- deviceSharesByFloor
24
- }: SankeyNodesArgs): SankeyChartLink[];
25
- //#endregion
26
- export { buildSankeyNodes };
27
- //# sourceMappingURL=build-sankey-nodes.d.ts.map