@epilot/spark-ui 0.20.0 → 0.20.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (314) hide show
  1. package/dist/components/accordion.cjs +7 -7
  2. package/dist/components/accordion.cjs.map +1 -1
  3. package/dist/components/accordion.d.ts +1 -1
  4. package/dist/components/accordion.js +1 -1
  5. package/dist/components/alert-dialog.cjs +10 -10
  6. package/dist/components/alert-dialog.cjs.map +1 -1
  7. package/dist/components/alert-dialog.js +1 -1
  8. package/dist/components/attachment.cjs +10 -10
  9. package/dist/components/attachment.cjs.map +1 -1
  10. package/dist/components/attachment.d.cts +2 -2
  11. package/dist/components/attachment.d.ts +2 -2
  12. package/dist/components/autocomplete.cjs +13 -13
  13. package/dist/components/autocomplete.cjs.map +1 -1
  14. package/dist/components/autocomplete.js +1 -1
  15. package/dist/components/avatar.cjs +2 -2
  16. package/dist/components/avatar.cjs.map +1 -1
  17. package/dist/components/avatar.js +1 -1
  18. package/dist/components/badge.cjs +2 -2
  19. package/dist/components/badge.cjs.map +1 -1
  20. package/dist/components/badge.js +2 -2
  21. package/dist/components/badge.js.map +1 -1
  22. package/dist/components/bar-chart-with-total.d.cts +1 -1
  23. package/dist/components/bar-chart-with-total.d.ts +1 -1
  24. package/dist/components/bar-chart.cjs +4 -4
  25. package/dist/components/bar-chart.cjs.map +1 -1
  26. package/dist/components/bar-chart.js +2 -2
  27. package/dist/components/bar-chart.js.map +1 -1
  28. package/dist/components/box.cjs +2 -2
  29. package/dist/components/box.cjs.map +1 -1
  30. package/dist/components/box.js +1 -1
  31. package/dist/components/breadcrumbs.cjs +7 -7
  32. package/dist/components/breadcrumbs.cjs.map +1 -1
  33. package/dist/components/bubble.cjs +5 -5
  34. package/dist/components/bubble.cjs.map +1 -1
  35. package/dist/components/bubble.d.cts +1 -1
  36. package/dist/components/bubble.d.ts +1 -1
  37. package/dist/components/button-group.cjs +5 -5
  38. package/dist/components/button-group.cjs.map +1 -1
  39. package/dist/components/button-group.js +1 -1
  40. package/dist/components/button.cjs +2 -2
  41. package/dist/components/button.cjs.map +1 -1
  42. package/dist/components/button.d.cts +3 -3
  43. package/dist/components/button.d.ts +3 -3
  44. package/dist/components/button.js +1 -1
  45. package/dist/components/button.js.map +1 -1
  46. package/dist/components/calendar.cjs +12 -11
  47. package/dist/components/calendar.cjs.map +1 -1
  48. package/dist/components/calendar.js +5 -4
  49. package/dist/components/calendar.js.map +1 -1
  50. package/dist/components/callout.cjs +8 -8
  51. package/dist/components/callout.cjs.map +1 -1
  52. package/dist/components/callout.d.ts +1 -1
  53. package/dist/components/callout.js +1 -1
  54. package/dist/components/card.cjs +16 -16
  55. package/dist/components/card.cjs.map +1 -1
  56. package/dist/components/card.js +2 -2
  57. package/dist/components/card.js.map +1 -1
  58. package/dist/components/chart.cjs +2 -2
  59. package/dist/components/chart.cjs.map +1 -1
  60. package/dist/components/checkbox.cjs +2 -2
  61. package/dist/components/checkbox.cjs.map +1 -1
  62. package/dist/components/checkbox.js +1 -1
  63. package/dist/components/checkbox.js.map +1 -1
  64. package/dist/components/circular-gauge.cjs +3 -3
  65. package/dist/components/circular-gauge.cjs.map +1 -1
  66. package/dist/components/circular-gauge.js +1 -1
  67. package/dist/components/circular-gauge.js.map +1 -1
  68. package/dist/components/day-of-week-picker.cjs +4 -4
  69. package/dist/components/day-of-week-picker.cjs.map +1 -1
  70. package/dist/components/dialog.cjs +9 -9
  71. package/dist/components/dialog.cjs.map +1 -1
  72. package/dist/components/dialog.js +1 -1
  73. package/dist/components/donut-chart.cjs.map +1 -1
  74. package/dist/components/donut-chart.js.map +1 -1
  75. package/dist/components/drawer.cjs +8 -8
  76. package/dist/components/drawer.cjs.map +1 -1
  77. package/dist/components/drawer.js +2 -2
  78. package/dist/components/drawer.js.map +1 -1
  79. package/dist/components/dropdown-menu.cjs +11 -11
  80. package/dist/components/dropdown-menu.cjs.map +1 -1
  81. package/dist/components/dropdown-menu.js +1 -1
  82. package/dist/components/empty-state.d.ts +1 -1
  83. package/dist/components/energy-breakdown.cjs +80 -0
  84. package/dist/components/energy-breakdown.cjs.map +1 -0
  85. package/dist/components/energy-breakdown.d.cts +24 -0
  86. package/dist/components/energy-breakdown.d.ts +24 -0
  87. package/dist/components/energy-breakdown.js +79 -0
  88. package/dist/components/energy-breakdown.js.map +1 -0
  89. package/dist/components/energy-history-chart.cjs +63 -0
  90. package/dist/components/energy-history-chart.cjs.map +1 -0
  91. package/dist/components/energy-history-chart.d.cts +64 -0
  92. package/dist/components/energy-history-chart.d.ts +64 -0
  93. package/dist/components/energy-history-chart.js +62 -0
  94. package/dist/components/energy-history-chart.js.map +1 -0
  95. package/dist/components/entity-card.cjs +11 -11
  96. package/dist/components/entity-card.cjs.map +1 -1
  97. package/dist/components/entity-card.d.ts +1 -1
  98. package/dist/components/field.cjs +16 -16
  99. package/dist/components/field.cjs.map +1 -1
  100. package/dist/components/field.js +1 -1
  101. package/dist/components/field.js.map +1 -1
  102. package/dist/components/hero-metric.cjs +4 -4
  103. package/dist/components/hero-metric.cjs.map +1 -1
  104. package/dist/components/icon.cjs +6 -6
  105. package/dist/components/icon.cjs.map +1 -1
  106. package/dist/components/icon.js +5 -5
  107. package/dist/components/icon.js.map +1 -1
  108. package/dist/components/info-block.cjs +9 -9
  109. package/dist/components/info-block.cjs.map +1 -1
  110. package/dist/components/info-block.d.cts +1 -1
  111. package/dist/components/info-block.d.ts +1 -1
  112. package/dist/components/input-date.cjs +5 -4
  113. package/dist/components/input-date.cjs.map +1 -1
  114. package/dist/components/input-date.d.cts +3 -1
  115. package/dist/components/input-date.d.ts +3 -1
  116. package/dist/components/input-date.js +3 -2
  117. package/dist/components/input-date.js.map +1 -1
  118. package/dist/components/input-group.cjs +5 -5
  119. package/dist/components/input-group.cjs.map +1 -1
  120. package/dist/components/input-otp.cjs +3 -3
  121. package/dist/components/input-otp.cjs.map +1 -1
  122. package/dist/components/input-otp.js +1 -1
  123. package/dist/components/input.cjs +3 -3
  124. package/dist/components/input.cjs.map +1 -1
  125. package/dist/components/input.js +1 -1
  126. package/dist/components/label.cjs +2 -2
  127. package/dist/components/label.cjs.map +1 -1
  128. package/dist/components/layout.cjs +2 -2
  129. package/dist/components/layout.cjs.map +1 -1
  130. package/dist/components/line-chart.cjs +7 -7
  131. package/dist/components/line-chart.cjs.map +1 -1
  132. package/dist/components/line-chart.js +5 -5
  133. package/dist/components/line-chart.js.map +1 -1
  134. package/dist/components/list.cjs +11 -11
  135. package/dist/components/list.cjs.map +1 -1
  136. package/dist/components/list.d.cts +7 -2
  137. package/dist/components/list.d.ts +7 -2
  138. package/dist/components/list.js +2 -2
  139. package/dist/components/list.js.map +1 -1
  140. package/dist/components/marker.cjs +4 -4
  141. package/dist/components/marker.cjs.map +1 -1
  142. package/dist/components/marker.d.cts +1 -1
  143. package/dist/components/marker.d.ts +1 -1
  144. package/dist/components/message-scroller.cjs +8 -8
  145. package/dist/components/message-scroller.cjs.map +1 -1
  146. package/dist/components/message-scroller.js +4 -4
  147. package/dist/components/message-scroller.js.map +1 -1
  148. package/dist/components/message.cjs +7 -7
  149. package/dist/components/message.cjs.map +1 -1
  150. package/dist/components/number-flow.d.cts +2 -12
  151. package/dist/components/number-flow.d.ts +2 -12
  152. package/dist/components/page-header.cjs +6 -6
  153. package/dist/components/page-header.cjs.map +1 -1
  154. package/dist/components/page-header.js +1 -1
  155. package/dist/components/period-tabs.cjs +6 -6
  156. package/dist/components/period-tabs.cjs.map +1 -1
  157. package/dist/components/pill.cjs +4 -4
  158. package/dist/components/pill.cjs.map +1 -1
  159. package/dist/components/pill.js +4 -4
  160. package/dist/components/pill.js.map +1 -1
  161. package/dist/components/popover.cjs +2 -2
  162. package/dist/components/popover.cjs.map +1 -1
  163. package/dist/components/power-history-chart.cjs +498 -0
  164. package/dist/components/power-history-chart.cjs.map +1 -0
  165. package/dist/components/power-history-chart.d.cts +71 -0
  166. package/dist/components/power-history-chart.d.ts +71 -0
  167. package/dist/components/power-history-chart.js +496 -0
  168. package/dist/components/power-history-chart.js.map +1 -0
  169. package/dist/components/power-network.cjs +559 -0
  170. package/dist/components/power-network.cjs.map +1 -0
  171. package/dist/components/power-network.d.cts +80 -0
  172. package/dist/components/power-network.d.ts +80 -0
  173. package/dist/components/power-network.js +553 -0
  174. package/dist/components/power-network.js.map +1 -0
  175. package/dist/components/progress.cjs +3 -3
  176. package/dist/components/progress.cjs.map +1 -1
  177. package/dist/components/progress.js +1 -1
  178. package/dist/components/progress.js.map +1 -1
  179. package/dist/components/radio-card-group.cjs +3 -3
  180. package/dist/components/radio-card-group.cjs.map +1 -1
  181. package/dist/components/radio.cjs +3 -3
  182. package/dist/components/radio.cjs.map +1 -1
  183. package/dist/components/radio.js +1 -1
  184. package/dist/components/sankey-chart.cjs +15 -5
  185. package/dist/components/sankey-chart.cjs.map +1 -1
  186. package/dist/components/sankey-chart.d.cts +3 -2
  187. package/dist/components/sankey-chart.d.ts +3 -2
  188. package/dist/components/sankey-chart.js +13 -4
  189. package/dist/components/sankey-chart.js.map +1 -1
  190. package/dist/components/schedule-editor.cjs +9 -9
  191. package/dist/components/schedule-editor.cjs.map +1 -1
  192. package/dist/components/schedule-list.cjs +11 -11
  193. package/dist/components/schedule-list.cjs.map +1 -1
  194. package/dist/components/schedule-list.js +1 -1
  195. package/dist/components/scroll-area.cjs +3 -3
  196. package/dist/components/scroll-area.cjs.map +1 -1
  197. package/dist/components/segmented-control.cjs +8 -8
  198. package/dist/components/segmented-control.cjs.map +1 -1
  199. package/dist/components/segmented-control.d.cts +2 -16
  200. package/dist/components/segmented-control.d.ts +2 -16
  201. package/dist/components/segmented-control.js +5 -5
  202. package/dist/components/segmented-control.js.map +1 -1
  203. package/dist/components/select.cjs +13 -13
  204. package/dist/components/select.cjs.map +1 -1
  205. package/dist/components/select.js +2 -2
  206. package/dist/components/separator.cjs +3 -3
  207. package/dist/components/separator.cjs.map +1 -1
  208. package/dist/components/series-legend.cjs +4 -4
  209. package/dist/components/series-legend.cjs.map +1 -1
  210. package/dist/components/sheet.cjs +9 -9
  211. package/dist/components/sheet.cjs.map +1 -1
  212. package/dist/components/sheet.js +1 -1
  213. package/dist/components/skeleton.cjs +3 -3
  214. package/dist/components/skeleton.cjs.map +1 -1
  215. package/dist/components/slider.cjs +11 -11
  216. package/dist/components/slider.cjs.map +1 -1
  217. package/dist/components/slider.js.map +1 -1
  218. package/dist/components/solar-forecast-chart.cjs +108 -0
  219. package/dist/components/solar-forecast-chart.cjs.map +1 -0
  220. package/dist/components/solar-forecast-chart.d.cts +77 -0
  221. package/dist/components/solar-forecast-chart.d.ts +77 -0
  222. package/dist/components/solar-forecast-chart.js +103 -0
  223. package/dist/components/solar-forecast-chart.js.map +1 -0
  224. package/dist/components/sortable-list.cjs +3 -3
  225. package/dist/components/sortable-list.cjs.map +1 -1
  226. package/dist/components/spinner.cjs +2 -2
  227. package/dist/components/spinner.cjs.map +1 -1
  228. package/dist/components/stat-card.cjs +8 -8
  229. package/dist/components/stat-card.cjs.map +1 -1
  230. package/dist/components/stepper.cjs +3 -3
  231. package/dist/components/stepper.cjs.map +1 -1
  232. package/dist/components/stepper.js +1 -1
  233. package/dist/components/switch.cjs +3 -3
  234. package/dist/components/switch.cjs.map +1 -1
  235. package/dist/components/switch.js +2 -2
  236. package/dist/components/switch.js.map +1 -1
  237. package/dist/components/table.cjs +9 -9
  238. package/dist/components/table.cjs.map +1 -1
  239. package/dist/components/table.js +1 -1
  240. package/dist/components/tabs.cjs +10 -10
  241. package/dist/components/tabs.cjs.map +1 -1
  242. package/dist/components/tabs.d.cts +1 -8
  243. package/dist/components/tabs.d.ts +1 -8
  244. package/dist/components/tabs.js +3 -3
  245. package/dist/components/tabs.js.map +1 -1
  246. package/dist/components/textarea.cjs +3 -3
  247. package/dist/components/textarea.cjs.map +1 -1
  248. package/dist/components/textarea.js +1 -1
  249. package/dist/components/theme.cjs +2 -2
  250. package/dist/components/theme.cjs.map +1 -1
  251. package/dist/components/theme.js +1 -1
  252. package/dist/components/thumbnail.cjs +3 -3
  253. package/dist/components/thumbnail.cjs.map +1 -1
  254. package/dist/components/time-picker.cjs +3 -3
  255. package/dist/components/time-picker.cjs.map +1 -1
  256. package/dist/components/toast.cjs +40 -15
  257. package/dist/components/toast.cjs.map +1 -1
  258. package/dist/components/toast.d.cts +15 -2
  259. package/dist/components/toast.d.ts +15 -2
  260. package/dist/components/toast.js +33 -8
  261. package/dist/components/toast.js.map +1 -1
  262. package/dist/components/toggle-group.cjs +40 -0
  263. package/dist/components/toggle-group.cjs.map +1 -0
  264. package/dist/components/toggle-group.d.cts +28 -0
  265. package/dist/components/toggle-group.d.ts +28 -0
  266. package/dist/components/toggle-group.js +37 -0
  267. package/dist/components/toggle-group.js.map +1 -0
  268. package/dist/components/toggle.cjs +69 -0
  269. package/dist/components/toggle.cjs.map +1 -0
  270. package/dist/components/toggle.d.cts +23 -0
  271. package/dist/components/toggle.d.ts +23 -0
  272. package/dist/components/toggle.js +66 -0
  273. package/dist/components/toggle.js.map +1 -0
  274. package/dist/components/tooltip.cjs +4 -4
  275. package/dist/components/tooltip.cjs.map +1 -1
  276. package/dist/components/tooltip.js +2 -2
  277. package/dist/components/tooltip.js.map +1 -1
  278. package/dist/components/typography.cjs +6 -6
  279. package/dist/components/typography.cjs.map +1 -1
  280. package/dist/components/wizard-layout.cjs +8 -8
  281. package/dist/components/wizard-layout.cjs.map +1 -1
  282. package/dist/lib/generate-radix-colors.cjs +1 -1
  283. package/dist/lib/generate-radix-colors.cjs.map +1 -1
  284. package/dist/lib/generate-radix-colors.js +1 -1
  285. package/dist/lib/generate-radix-colors.js.map +1 -1
  286. package/dist/lib/input-box-variants.cjs +9 -9
  287. package/dist/lib/input-box-variants.cjs.map +1 -1
  288. package/dist/lib/toggle-group-context.cjs +12 -0
  289. package/dist/lib/toggle-group-context.cjs.map +1 -0
  290. package/dist/lib/toggle-group-context.d.cts +17 -0
  291. package/dist/lib/toggle-group-context.d.ts +17 -0
  292. package/dist/lib/toggle-group-context.js +9 -0
  293. package/dist/lib/toggle-group-context.js.map +1 -0
  294. package/dist/number-flow-Bch81ixZ.d.cts +14 -0
  295. package/dist/number-flow-Bch81ixZ.d.ts +14 -0
  296. package/dist/styles/spark-default.css +11 -0
  297. package/dist/styles/theme.css +15 -4
  298. package/dist/utils/build-sankey-nodes.cjs +72 -0
  299. package/dist/utils/build-sankey-nodes.cjs.map +1 -0
  300. package/dist/utils/build-sankey-nodes.d.cts +27 -0
  301. package/dist/utils/build-sankey-nodes.d.ts +27 -0
  302. package/dist/utils/build-sankey-nodes.js +71 -0
  303. package/dist/utils/build-sankey-nodes.js.map +1 -0
  304. package/dist/utils/cn.cjs +2 -2
  305. package/dist/utils/cn.d.cts +1 -1
  306. package/dist/utils/cn.d.ts +1 -1
  307. package/dist/utils/cn.js +1 -1
  308. package/dist/utils/format.cjs +14 -0
  309. package/dist/utils/format.cjs.map +1 -1
  310. package/dist/utils/format.d.cts +8 -1
  311. package/dist/utils/format.d.ts +8 -1
  312. package/dist/utils/format.js +12 -1
  313. package/dist/utils/format.js.map +1 -1
  314. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"input-otp.cjs","names":["GHOST_UNDERLINE","boxChrome","useFieldControl","OTPField"],"sources":["../../src/components/input-otp.tsx"],"sourcesContent":["import { OTPField, type OTPFieldRootProps } from '@base-ui/react/otp-field'\nimport { cva } from 'class-variance-authority'\nimport { boxChrome, GHOST_UNDERLINE } from '../lib/input-box-variants'\nimport { cn } from '../utils/cn'\nimport { useFieldControl } from './field'\n\n// One code box per slot. Mirrors Input's box/underline carrier model so the\n// slots read like the rest of the input family across every style/color knob.\nconst slotVariants = cva(\n 'flex w-11 min-w-0 items-center justify-center bg-transparent text-center text-base font-medium text-gray tabular-nums outline-hidden transition-all group-data-[invalid=true]/field:text-error placeholder:text-gray-placeholder disabled:cursor-not-allowed disabled:text-gray-disabled disabled:placeholder:text-gray-disabled aria-invalid:text-error motion-reduce:transition-none',\n {\n variants: {\n chrome: {\n // inside an inset field the shell is the box; slots keep the classic\n // underline (the pre-knob default look)\n inset: GHOST_UNDERLINE,\n box: 'h-11 rounded-md',\n },\n inputStyle: { soft: '', surface: '', outlined: '', ghost: '' },\n inputColor: { brand: '', gray: '' },\n },\n compoundVariants: [\n {\n chrome: 'box',\n inputStyle: 'soft',\n inputColor: 'brand',\n class: boxChrome.soft.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'soft',\n inputColor: 'gray',\n class: boxChrome.soft.gray,\n },\n {\n chrome: 'box',\n inputStyle: 'surface',\n inputColor: 'brand',\n class: boxChrome.surface.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'surface',\n inputColor: 'gray',\n class: boxChrome.surface.gray,\n },\n {\n chrome: 'box',\n inputStyle: 'outlined',\n inputColor: 'brand',\n class: boxChrome.outlined.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'outlined',\n inputColor: 'gray',\n class: boxChrome.outlined.gray,\n },\n {\n chrome: 'box',\n inputStyle: 'ghost',\n inputColor: 'brand',\n class: boxChrome.ghost.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'ghost',\n inputColor: 'gray',\n class: boxChrome.ghost.gray,\n },\n { chrome: 'inset', inputColor: 'brand', class: 'border-b-input' },\n { chrome: 'inset', inputColor: 'gray', class: 'border-b-input-gray' },\n ],\n },\n)\n\ninterface InputOtpProps extends Pick<\n OTPFieldRootProps,\n | 'value'\n | 'defaultValue'\n | 'onValueChange'\n | 'disabled'\n | 'className'\n | 'id'\n | 'validationType'\n> {\n /** Number of code slots. */\n length?: number\n /** Fired when every slot is filled. */\n onComplete?: OTPFieldRootProps['onValueComplete']\n /** Accessible name per slot (for localization). */\n slotAriaLabel?: (index: number) => string\n}\n\nfunction InputOtp({\n length = 6,\n className,\n id: idProp,\n onComplete,\n slotAriaLabel = (index) => `Character ${index + 1}`,\n validationType = 'alphanumeric',\n ...props\n}: InputOtpProps) {\n const { field, id, ariaDescribedBy, ariaInvalid, inputStyle, inputColor } =\n useFieldControl({ id: idProp })\n const chrome = field?.labelPosition === 'inset' ? 'inset' : 'box'\n\n return (\n <OTPField.Root\n data-slot=\"input-otp\"\n length={length}\n id={id}\n validationType={validationType}\n onValueComplete={onComplete}\n className={cn('flex items-center gap-2', className)}\n {...props}\n >\n {Array.from({ length }, (_, index) => (\n <OTPField.Input\n key={index}\n // the first slot is named by the Field label (Base UI ignores\n // aria-label there); the rest get a positional name for a11y\n aria-label={index === 0 ? undefined : slotAriaLabel(index)}\n aria-describedby={index === 0 ? ariaDescribedBy : undefined}\n aria-invalid={index === 0 ? ariaInvalid : undefined}\n className={slotVariants({ chrome, inputStyle, inputColor })}\n />\n ))}\n </OTPField.Root>\n )\n}\n\nexport { InputOtp }\nexport type { InputOtpProps }\n"],"mappings":";;;;;;;;;AAQA,MAAM,gBAAA,GAAA,yBAAA,KACJ,0XACA;CACE,UAAU;EACR,QAAQ;GAGN,OAAOA,+BAAAA;GACP,KAAK;EACP;EACA,YAAY;GAAE,MAAM;GAAI,SAAS;GAAI,UAAU;GAAI,OAAO;EAAG;EAC7D,YAAY;GAAE,OAAO;GAAI,MAAM;EAAG;CACpC;CACA,kBAAkB;EAChB;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOC,+BAAAA,UAAU,KAAK;EACxB;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,KAAK;EACxB;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,QAAQ;EAC3B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,QAAQ;EAC3B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,SAAS;EAC5B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,SAAS;EAC5B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,MAAM;EACzB;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,MAAM;EACzB;EACA;GAAE,QAAQ;GAAS,YAAY;GAAS,OAAO;EAAiB;EAChE;GAAE,QAAQ;GAAS,YAAY;GAAQ,OAAO;EAAsB;CACtE;AACF,CACF;AAoBA,SAAS,SAAS,EAChB,SAAS,GACT,WACA,IAAI,QACJ,YACA,iBAAiB,UAAU,aAAa,QAAQ,KAChD,iBAAiB,gBACjB,GAAG,SACa;CAChB,MAAM,EAAE,OAAO,IAAI,iBAAiB,aAAa,YAAY,eAC3DC,yBAAAA,gBAAgB,EAAE,IAAI,OAAO,CAAC;CAChC,MAAM,SAAS,OAAO,kBAAkB,UAAU,UAAU;CAE5D,OACE,iBAAA,GAAA,kBAAA,KAACC,yBAAAA,SAAS,MAAV;EACE,aAAU;EACF;EACJ;EACY;EAChB,iBAAiB;EACjB,YAAA,GAAA,OAAA,IAAc,2BAA2B,SAAS;EAClD,GAAI;YAEH,MAAM,KAAK,EAAE,OAAO,IAAI,GAAG,UAC1B,iBAAA,GAAA,kBAAA,KAACA,yBAAAA,SAAS,OAAV;GAIE,cAAY,UAAU,IAAI,KAAA,IAAY,cAAc,KAAK;GACzD,oBAAkB,UAAU,IAAI,kBAAkB,KAAA;GAClD,gBAAc,UAAU,IAAI,cAAc,KAAA;GAC1C,WAAW,aAAa;IAAE;IAAQ;IAAY;GAAW,CAAC;EAC3D,GAPM,KAON,CACF;CACY,CAAA;AAEnB"}
1
+ {"version":3,"file":"input-otp.cjs","names":["GHOST_UNDERLINE","boxChrome","useFieldControl","OTPField"],"sources":["../../src/components/input-otp.tsx"],"sourcesContent":["import { OTPField, type OTPFieldRootProps } from '@base-ui/react/otp-field'\nimport { cva } from 'class-variance-authority'\nimport { boxChrome, GHOST_UNDERLINE } from '../lib/input-box-variants'\nimport { cn } from '../utils/cn'\nimport { useFieldControl } from './field'\n\n// One code box per slot. Mirrors Input's box/underline carrier model so the\n// slots read like the rest of the input family across every style/color knob.\nconst slotVariants = cva(\n 'flex w-11 min-w-0 items-center justify-center bg-transparent text-center text-base font-medium text-gray tabular-nums outline-hidden transition-all group-data-[invalid=true]/field:text-error placeholder:text-gray-placeholder disabled:cursor-not-allowed disabled:text-gray-disabled disabled:placeholder:text-gray-disabled aria-invalid:text-error motion-reduce:transition-none',\n {\n variants: {\n chrome: {\n // inside an inset field the shell is the box; slots keep the classic\n // underline (the pre-knob default look)\n inset: GHOST_UNDERLINE,\n box: 'h-11 rounded-md',\n },\n inputStyle: { soft: '', surface: '', outlined: '', ghost: '' },\n inputColor: { brand: '', gray: '' },\n },\n compoundVariants: [\n {\n chrome: 'box',\n inputStyle: 'soft',\n inputColor: 'brand',\n class: boxChrome.soft.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'soft',\n inputColor: 'gray',\n class: boxChrome.soft.gray,\n },\n {\n chrome: 'box',\n inputStyle: 'surface',\n inputColor: 'brand',\n class: boxChrome.surface.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'surface',\n inputColor: 'gray',\n class: boxChrome.surface.gray,\n },\n {\n chrome: 'box',\n inputStyle: 'outlined',\n inputColor: 'brand',\n class: boxChrome.outlined.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'outlined',\n inputColor: 'gray',\n class: boxChrome.outlined.gray,\n },\n {\n chrome: 'box',\n inputStyle: 'ghost',\n inputColor: 'brand',\n class: boxChrome.ghost.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'ghost',\n inputColor: 'gray',\n class: boxChrome.ghost.gray,\n },\n { chrome: 'inset', inputColor: 'brand', class: 'border-b-input' },\n { chrome: 'inset', inputColor: 'gray', class: 'border-b-input-gray' },\n ],\n },\n)\n\ninterface InputOtpProps extends Pick<\n OTPFieldRootProps,\n | 'value'\n | 'defaultValue'\n | 'onValueChange'\n | 'disabled'\n | 'className'\n | 'id'\n | 'validationType'\n> {\n /** Number of code slots. */\n length?: number\n /** Fired when every slot is filled. */\n onComplete?: OTPFieldRootProps['onValueComplete']\n /** Accessible name per slot (for localization). */\n slotAriaLabel?: (index: number) => string\n}\n\nfunction InputOtp({\n length = 6,\n className,\n id: idProp,\n onComplete,\n slotAriaLabel = (index) => `Character ${index + 1}`,\n validationType = 'alphanumeric',\n ...props\n}: InputOtpProps) {\n const { field, id, ariaDescribedBy, ariaInvalid, inputStyle, inputColor } =\n useFieldControl({ id: idProp })\n const chrome = field?.labelPosition === 'inset' ? 'inset' : 'box'\n\n return (\n <OTPField.Root\n data-slot=\"input-otp\"\n length={length}\n id={id}\n validationType={validationType}\n onValueComplete={onComplete}\n className={cn('flex items-center gap-2', className)}\n {...props}\n >\n {Array.from({ length }, (_, index) => (\n <OTPField.Input\n key={index}\n // the first slot is named by the Field label (Base UI ignores\n // aria-label there); the rest get a positional name for a11y\n aria-label={index === 0 ? undefined : slotAriaLabel(index)}\n aria-describedby={index === 0 ? ariaDescribedBy : undefined}\n aria-invalid={index === 0 ? ariaInvalid : undefined}\n className={slotVariants({ chrome, inputStyle, inputColor })}\n />\n ))}\n </OTPField.Root>\n )\n}\n\nexport { InputOtp }\nexport type { InputOtpProps }\n"],"mappings":";;;;;;;;;AAQA,MAAM,gBAAA,GAAA,yBAAA,KACJ,0XACA;CACE,UAAU;EACR,QAAQ;GAGN,OAAOA,+BAAAA;GACP,KAAK;EACP;EACA,YAAY;GAAE,MAAM;GAAI,SAAS;GAAI,UAAU;GAAI,OAAO;EAAG;EAC7D,YAAY;GAAE,OAAO;GAAI,MAAM;EAAG;CACpC;CACA,kBAAkB;EAChB;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOC,+BAAAA,UAAU,KAAK;EACxB;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,KAAK;EACxB;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,QAAQ;EAC3B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,QAAQ;EAC3B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,SAAS;EAC5B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,SAAS;EAC5B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,MAAM;EACzB;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,MAAM;EACzB;EACA;GAAE,QAAQ;GAAS,YAAY;GAAS,OAAO;EAAiB;EAChE;GAAE,QAAQ;GAAS,YAAY;GAAQ,OAAO;EAAsB;CACtE;AACF,CACF;AAoBA,SAAS,SAAS,EAChB,SAAS,GACT,WACA,IAAI,QACJ,YACA,iBAAiB,UAAU,aAAa,QAAQ,KAChD,iBAAiB,gBACjB,GAAG,SACa;CAChB,MAAM,EAAE,OAAO,IAAI,iBAAiB,aAAa,YAAY,eAC3DC,yBAAAA,gBAAgB,EAAE,IAAI,OAAO,CAAC;CAChC,MAAM,SAAS,OAAO,kBAAkB,UAAU,UAAU;CAE5D,OACE,iBAAA,GAAA,kBAAA,KAACC,yBAAAA,SAAS,MAAV;EACE,aAAU;EACF;EACJ;EACY;EAChB,iBAAiB;EACjB,YAAA,GAAA,GAAA,IAAc,2BAA2B,SAAS;EAClD,GAAI;YAEH,MAAM,KAAK,EAAE,OAAO,IAAI,GAAG,UAC1B,iBAAA,GAAA,kBAAA,KAACA,yBAAAA,SAAS,OAAV;GAIE,cAAY,UAAU,IAAI,KAAA,IAAY,cAAc,KAAK;GACzD,oBAAkB,UAAU,IAAI,kBAAkB,KAAA;GAClD,gBAAc,UAAU,IAAI,cAAc,KAAA;GAC1C,WAAW,aAAa;IAAE;IAAQ;IAAY;GAAW,CAAC;EAC3D,GAPM,KAON,CACF;CACY,CAAA;AAEnB"}
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { cn } from "../utils/cn.js";
3
- import { useFieldControl } from "./field.js";
4
3
  import { GHOST_UNDERLINE, boxChrome } from "../lib/input-box-variants.js";
4
+ import { useFieldControl } from "./field.js";
5
5
  import { jsx } from "react/jsx-runtime";
6
6
  import { cva } from "class-variance-authority";
7
7
  import { OTPField } from "@base-ui/react/otp-field";
@@ -1,13 +1,13 @@
1
1
  "use client";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const require_chunk = require("../chunk-DY84GLCh.cjs");
4
- const require_components_field = require("./field.cjs");
5
4
  const require_lib_input_box_variants = require("../lib/input-box-variants.cjs");
5
+ const require_components_field = require("./field.cjs");
6
6
  let react = require("react");
7
7
  react = require_chunk.__toESM(react);
8
8
  let react_jsx_runtime = require("react/jsx-runtime");
9
9
  let class_variance_authority = require("class-variance-authority");
10
- let cnfast = require("cnfast");
10
+ let cn = require("cn");
11
11
  //#region src/components/input.tsx
12
12
  const inputVariants = (0, class_variance_authority.cva)("flex h-10 w-full min-w-0 [appearance:textfield] bg-transparent text-gray outline-hidden transition-all group-data-[invalid=true]/field:text-error placeholder:text-gray-placeholder disabled:cursor-not-allowed disabled:text-gray-disabled disabled:placeholder:text-gray-disabled aria-invalid:text-error motion-reduce:transition-none [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none", {
13
13
  variants: {
@@ -96,7 +96,7 @@ const Input = react.forwardRef(function Input({ variant, className, id: idProp,
96
96
  });
97
97
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
98
98
  "data-slot": "input",
99
- className: (0, cnfast.cn)(inputVariants({
99
+ className: (0, cn.cn)(inputVariants({
100
100
  chrome: variant === "none" ? "none" : !variant && field?.labelPosition === "inset" ? "inset" : "box",
101
101
  inputStyle,
102
102
  inputColor
@@ -1 +1 @@
1
- {"version":3,"file":"input.cjs","names":["GHOST_UNDERLINE","boxChrome","React","useFieldControl"],"sources":["../../src/components/input.tsx"],"sourcesContent":["import { cva } from 'class-variance-authority'\nimport * as React from 'react'\nimport { boxChrome, GHOST_UNDERLINE } from '../lib/input-box-variants'\nimport type { SparkInputStyle } from '../lib/theme-types'\nimport { cn } from '../utils/cn'\nimport { useFieldControl } from './field'\n\ntype InputVariant = SparkInputStyle | 'none'\n\nconst inputVariants = cva(\n 'flex h-10 w-full min-w-0 [appearance:textfield] bg-transparent text-gray outline-hidden transition-all group-data-[invalid=true]/field:text-error placeholder:text-gray-placeholder disabled:cursor-not-allowed disabled:text-gray-disabled disabled:placeholder:text-gray-disabled aria-invalid:text-error motion-reduce:transition-none [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none',\n {\n variants: {\n chrome: {\n none: 'border-0 px-0',\n // inside an inset field the shell is the box; the input keeps the\n // classic underline (the pre-knob default look)\n inset: GHOST_UNDERLINE,\n box: 'h-11 rounded-md px-3 py-1 text-base transition-all motion-reduce:transition-none',\n },\n inputStyle: { soft: '', surface: '', outlined: '', ghost: '' },\n inputColor: { brand: '', gray: '' },\n },\n compoundVariants: [\n {\n chrome: 'box',\n inputStyle: 'soft',\n inputColor: 'brand',\n class: boxChrome.soft.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'soft',\n inputColor: 'gray',\n class: boxChrome.soft.gray,\n },\n {\n chrome: 'box',\n inputStyle: 'surface',\n inputColor: 'brand',\n class: boxChrome.surface.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'surface',\n inputColor: 'gray',\n class: boxChrome.surface.gray,\n },\n {\n chrome: 'box',\n inputStyle: 'outlined',\n inputColor: 'brand',\n class: boxChrome.outlined.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'outlined',\n inputColor: 'gray',\n class: boxChrome.outlined.gray,\n },\n {\n chrome: 'box',\n inputStyle: 'ghost',\n inputColor: 'brand',\n class: boxChrome.ghost.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'ghost',\n inputColor: 'gray',\n class: boxChrome.ghost.gray,\n },\n { chrome: 'inset', inputColor: 'brand', class: 'border-b-input' },\n { chrome: 'inset', inputColor: 'gray', class: 'border-b-input-gray' },\n ],\n },\n)\n\ninterface InputProps extends React.ComponentProps<'input'> {\n variant?: InputVariant\n}\n\n// forwardRef keeps refs working for React 18 consumers (ref-as-prop is 19-only)\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(function Input(\n {\n variant,\n className,\n id: idProp,\n 'aria-describedby': ariaDescribedByProp,\n ...props\n },\n ref,\n) {\n const { field, id, ariaDescribedBy, ariaInvalid, inputStyle, inputColor } =\n useFieldControl({\n id: idProp,\n ariaDescribedBy: ariaDescribedByProp,\n variant: variant !== 'none' ? variant : undefined,\n })\n // an explicit variant prop keeps the box even inside an inset field\n const chrome =\n variant === 'none'\n ? 'none'\n : !variant && field?.labelPosition === 'inset'\n ? 'inset'\n : 'box'\n\n return (\n <input\n data-slot=\"input\"\n className={cn(\n inputVariants({ chrome, inputStyle, inputColor }),\n className,\n )}\n id={id}\n ref={ref}\n aria-invalid={ariaInvalid}\n {...props}\n aria-describedby={ariaDescribedBy}\n />\n )\n})\n\nexport { Input }\nexport type { InputProps, InputVariant }\n"],"mappings":";;;;;;;;;;;AASA,MAAM,iBAAA,GAAA,yBAAA,KACJ,2aACA;CACE,UAAU;EACR,QAAQ;GACN,MAAM;GAGN,OAAOA,+BAAAA;GACP,KAAK;EACP;EACA,YAAY;GAAE,MAAM;GAAI,SAAS;GAAI,UAAU;GAAI,OAAO;EAAG;EAC7D,YAAY;GAAE,OAAO;GAAI,MAAM;EAAG;CACpC;CACA,kBAAkB;EAChB;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOC,+BAAAA,UAAU,KAAK;EACxB;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,KAAK;EACxB;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,QAAQ;EAC3B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,QAAQ;EAC3B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,SAAS;EAC5B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,SAAS;EAC5B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,MAAM;EACzB;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,MAAM;EACzB;EACA;GAAE,QAAQ;GAAS,YAAY;GAAS,OAAO;EAAiB;EAChE;GAAE,QAAQ;GAAS,YAAY;GAAQ,OAAO;EAAsB;CACtE;AACF,CACF;AAOA,MAAM,QAAQC,MAAM,WAAyC,SAAS,MACpE,EACE,SACA,WACA,IAAI,QACJ,oBAAoB,qBACpB,GAAG,SAEL,KACA;CACA,MAAM,EAAE,OAAO,IAAI,iBAAiB,aAAa,YAAY,eAC3DC,yBAAAA,gBAAgB;EACd,IAAI;EACJ,iBAAiB;EACjB,SAAS,YAAY,SAAS,UAAU,KAAA;CAC1C,CAAC;CASH,OACE,iBAAA,GAAA,kBAAA,KAAC,SAAD;EACE,aAAU;EACV,YAAA,GAAA,OAAA,IACE,cAAc;GAAE,QAVpB,YAAY,SACR,SACA,CAAC,WAAW,OAAO,kBAAkB,UACnC,UACA;GAMsB;GAAY;EAAW,CAAC,GAChD,SACF;EACI;EACC;EACL,gBAAc;EACd,GAAI;EACJ,oBAAkB;CACnB,CAAA;AAEL,CAAC"}
1
+ {"version":3,"file":"input.cjs","names":["GHOST_UNDERLINE","boxChrome","React","useFieldControl"],"sources":["../../src/components/input.tsx"],"sourcesContent":["import { cva } from 'class-variance-authority'\nimport * as React from 'react'\nimport { boxChrome, GHOST_UNDERLINE } from '../lib/input-box-variants'\nimport type { SparkInputStyle } from '../lib/theme-types'\nimport { cn } from '../utils/cn'\nimport { useFieldControl } from './field'\n\ntype InputVariant = SparkInputStyle | 'none'\n\nconst inputVariants = cva(\n 'flex h-10 w-full min-w-0 [appearance:textfield] bg-transparent text-gray outline-hidden transition-all group-data-[invalid=true]/field:text-error placeholder:text-gray-placeholder disabled:cursor-not-allowed disabled:text-gray-disabled disabled:placeholder:text-gray-disabled aria-invalid:text-error motion-reduce:transition-none [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none',\n {\n variants: {\n chrome: {\n none: 'border-0 px-0',\n // inside an inset field the shell is the box; the input keeps the\n // classic underline (the pre-knob default look)\n inset: GHOST_UNDERLINE,\n box: 'h-11 rounded-md px-3 py-1 text-base transition-all motion-reduce:transition-none',\n },\n inputStyle: { soft: '', surface: '', outlined: '', ghost: '' },\n inputColor: { brand: '', gray: '' },\n },\n compoundVariants: [\n {\n chrome: 'box',\n inputStyle: 'soft',\n inputColor: 'brand',\n class: boxChrome.soft.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'soft',\n inputColor: 'gray',\n class: boxChrome.soft.gray,\n },\n {\n chrome: 'box',\n inputStyle: 'surface',\n inputColor: 'brand',\n class: boxChrome.surface.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'surface',\n inputColor: 'gray',\n class: boxChrome.surface.gray,\n },\n {\n chrome: 'box',\n inputStyle: 'outlined',\n inputColor: 'brand',\n class: boxChrome.outlined.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'outlined',\n inputColor: 'gray',\n class: boxChrome.outlined.gray,\n },\n {\n chrome: 'box',\n inputStyle: 'ghost',\n inputColor: 'brand',\n class: boxChrome.ghost.brand,\n },\n {\n chrome: 'box',\n inputStyle: 'ghost',\n inputColor: 'gray',\n class: boxChrome.ghost.gray,\n },\n { chrome: 'inset', inputColor: 'brand', class: 'border-b-input' },\n { chrome: 'inset', inputColor: 'gray', class: 'border-b-input-gray' },\n ],\n },\n)\n\ninterface InputProps extends React.ComponentProps<'input'> {\n variant?: InputVariant\n}\n\n// forwardRef keeps refs working for React 18 consumers (ref-as-prop is 19-only)\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(function Input(\n {\n variant,\n className,\n id: idProp,\n 'aria-describedby': ariaDescribedByProp,\n ...props\n },\n ref,\n) {\n const { field, id, ariaDescribedBy, ariaInvalid, inputStyle, inputColor } =\n useFieldControl({\n id: idProp,\n ariaDescribedBy: ariaDescribedByProp,\n variant: variant !== 'none' ? variant : undefined,\n })\n // an explicit variant prop keeps the box even inside an inset field\n const chrome =\n variant === 'none'\n ? 'none'\n : !variant && field?.labelPosition === 'inset'\n ? 'inset'\n : 'box'\n\n return (\n <input\n data-slot=\"input\"\n className={cn(\n inputVariants({ chrome, inputStyle, inputColor }),\n className,\n )}\n id={id}\n ref={ref}\n aria-invalid={ariaInvalid}\n {...props}\n aria-describedby={ariaDescribedBy}\n />\n )\n})\n\nexport { Input }\nexport type { InputProps, InputVariant }\n"],"mappings":";;;;;;;;;;;AASA,MAAM,iBAAA,GAAA,yBAAA,KACJ,2aACA;CACE,UAAU;EACR,QAAQ;GACN,MAAM;GAGN,OAAOA,+BAAAA;GACP,KAAK;EACP;EACA,YAAY;GAAE,MAAM;GAAI,SAAS;GAAI,UAAU;GAAI,OAAO;EAAG;EAC7D,YAAY;GAAE,OAAO;GAAI,MAAM;EAAG;CACpC;CACA,kBAAkB;EAChB;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOC,+BAAAA,UAAU,KAAK;EACxB;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,KAAK;EACxB;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,QAAQ;EAC3B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,QAAQ;EAC3B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,SAAS;EAC5B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,SAAS;EAC5B;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,MAAM;EACzB;EACA;GACE,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,OAAOA,+BAAAA,UAAU,MAAM;EACzB;EACA;GAAE,QAAQ;GAAS,YAAY;GAAS,OAAO;EAAiB;EAChE;GAAE,QAAQ;GAAS,YAAY;GAAQ,OAAO;EAAsB;CACtE;AACF,CACF;AAOA,MAAM,QAAQC,MAAM,WAAyC,SAAS,MACpE,EACE,SACA,WACA,IAAI,QACJ,oBAAoB,qBACpB,GAAG,SAEL,KACA;CACA,MAAM,EAAE,OAAO,IAAI,iBAAiB,aAAa,YAAY,eAC3DC,yBAAAA,gBAAgB;EACd,IAAI;EACJ,iBAAiB;EACjB,SAAS,YAAY,SAAS,UAAU,KAAA;CAC1C,CAAC;CASH,OACE,iBAAA,GAAA,kBAAA,KAAC,SAAD;EACE,aAAU;EACV,YAAA,GAAA,GAAA,IACE,cAAc;GAAE,QAVpB,YAAY,SACR,SACA,CAAC,WAAW,OAAO,kBAAkB,UACnC,UACA;GAMsB;GAAY;EAAW,CAAC,GAChD,SACF;EACI;EACC;EACL,gBAAc;EACd,GAAI;EACJ,oBAAkB;CACnB,CAAA;AAEL,CAAC"}
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { cn } from "../utils/cn.js";
3
- import { useFieldControl } from "./field.js";
4
3
  import { GHOST_UNDERLINE, boxChrome } from "../lib/input-box-variants.js";
4
+ import { useFieldControl } from "./field.js";
5
5
  import * as React$1 from "react";
6
6
  import { jsx } from "react/jsx-runtime";
7
7
  import { cva } from "class-variance-authority";
@@ -4,10 +4,10 @@ const require_chunk = require("../chunk-DY84GLCh.cjs");
4
4
  let react = require("react");
5
5
  react = require_chunk.__toESM(react);
6
6
  let react_jsx_runtime = require("react/jsx-runtime");
7
- let cnfast = require("cnfast");
7
+ let cn = require("cn");
8
8
  //#region src/components/label.tsx
9
9
  const Label = react.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
10
- className: (0, cnfast.cn)("text-sm leading-5 font-normal text-gray", className),
10
+ className: (0, cn.cn)("text-sm leading-5 font-normal text-gray", className),
11
11
  ref,
12
12
  ...props
13
13
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"label.cjs","names":["React"],"sources":["../../src/components/label.tsx"],"sourcesContent":["import * as React from 'react'\nimport { cn } from '../utils/cn'\n\ninterface LabelProps extends React.LabelHTMLAttributes<HTMLLabelElement> {}\n\nconst Label = React.forwardRef<HTMLLabelElement, LabelProps>(\n ({ className, ...props }, ref) => (\n <label\n className={cn('text-sm leading-5 font-normal text-gray', className)}\n ref={ref}\n {...props}\n />\n ),\n)\n\nLabel.displayName = 'Label'\n\nexport { Label }\nexport type { LabelProps }\n"],"mappings":";;;;;;;;AAKA,MAAM,QAAQA,MAAM,YACjB,EAAE,WAAW,GAAG,SAAS,QACxB,iBAAA,GAAA,kBAAA,KAAC,SAAD;CACE,YAAA,GAAA,OAAA,IAAc,2CAA2C,SAAS;CAC7D;CACL,GAAI;AACL,CAAA,CAEL;AAEA,MAAM,cAAc"}
1
+ {"version":3,"file":"label.cjs","names":["React"],"sources":["../../src/components/label.tsx"],"sourcesContent":["import * as React from 'react'\nimport { cn } from '../utils/cn'\n\ninterface LabelProps extends React.LabelHTMLAttributes<HTMLLabelElement> {}\n\nconst Label = React.forwardRef<HTMLLabelElement, LabelProps>(\n ({ className, ...props }, ref) => (\n <label\n className={cn('text-sm leading-5 font-normal text-gray', className)}\n ref={ref}\n {...props}\n />\n ),\n)\n\nLabel.displayName = 'Label'\n\nexport { Label }\nexport type { LabelProps }\n"],"mappings":";;;;;;;;AAKA,MAAM,QAAQA,MAAM,YACjB,EAAE,WAAW,GAAG,SAAS,QACxB,iBAAA,GAAA,kBAAA,KAAC,SAAD;CACE,YAAA,GAAA,GAAA,IAAc,2CAA2C,SAAS;CAC7D;CACL,GAAI;AACL,CAAA,CAEL;AAEA,MAAM,cAAc"}
@@ -1,10 +1,10 @@
1
1
  "use client";
2
2
  let react_jsx_runtime = require("react/jsx-runtime");
3
- let cnfast = require("cnfast");
3
+ let cn = require("cn");
4
4
  //#region src/components/layout.tsx
5
5
  const PageContainer = ({ className, gap = 4, style, ...rest }) => {
6
6
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7
- className: (0, cnfast.cn)("mx-auto flex w-full flex-col gap-[calc(var(--spark-layout-gap)*var(--page-container-gap-steps,4))] md:max-w-152", className),
7
+ className: (0, cn.cn)("mx-auto flex w-full flex-col gap-[calc(var(--spark-layout-gap)*var(--page-container-gap-steps,4))] md:max-w-152", className),
8
8
  style: {
9
9
  "--page-container-gap-steps": gap,
10
10
  ...style
@@ -1 +1 @@
1
- {"version":3,"file":"layout.cjs","names":[],"sources":["../../src/components/layout.tsx"],"sourcesContent":["import type React from 'react'\nimport { cn } from '../utils/cn'\n\ninterface PageContainerProps extends React.ComponentProps<'div'> {\n /** How many `--spark-layout-gap` units apart each section sits. */\n gap?: number\n}\n\nconst PageContainer = ({\n className,\n gap = 4,\n style,\n ...rest\n}: PageContainerProps) => {\n return (\n <div\n className={cn(\n 'mx-auto flex w-full flex-col gap-[calc(var(--spark-layout-gap)*var(--page-container-gap-steps,4))] md:max-w-152',\n className,\n )}\n style={\n {\n '--page-container-gap-steps': gap,\n ...style,\n } as React.CSSProperties\n }\n {...rest}\n />\n )\n}\n\nexport default PageContainer\nexport type { PageContainerProps }\n"],"mappings":";;;;AAQA,MAAM,iBAAiB,EACrB,WACA,MAAM,GACN,OACA,GAAG,WACqB;CACxB,OACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;EACE,YAAA,GAAA,OAAA,IACE,mHACA,SACF;EACA,OACE;GACE,8BAA8B;GAC9B,GAAG;EACL;EAEF,GAAI;CACL,CAAA;AAEL"}
1
+ {"version":3,"file":"layout.cjs","names":[],"sources":["../../src/components/layout.tsx"],"sourcesContent":["import type React from 'react'\nimport { cn } from '../utils/cn'\n\ninterface PageContainerProps extends React.ComponentProps<'div'> {\n /** How many `--spark-layout-gap` units apart each section sits. */\n gap?: number\n}\n\nconst PageContainer = ({\n className,\n gap = 4,\n style,\n ...rest\n}: PageContainerProps) => {\n return (\n <div\n className={cn(\n 'mx-auto flex w-full flex-col gap-[calc(var(--spark-layout-gap)*var(--page-container-gap-steps,4))] md:max-w-152',\n className,\n )}\n style={\n {\n '--page-container-gap-steps': gap,\n ...style,\n } as React.CSSProperties\n }\n {...rest}\n />\n )\n}\n\nexport default PageContainer\nexport type { PageContainerProps }\n"],"mappings":";;;;AAQA,MAAM,iBAAiB,EACrB,WACA,MAAM,GACN,OACA,GAAG,WACqB;CACxB,OACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;EACE,YAAA,GAAA,GAAA,IACE,mHACA,SACF;EACA,OACE;GACE,8BAA8B;GAC9B,GAAG;EACL;EAEF,GAAI;CACL,CAAA;AAEL"}
@@ -1,12 +1,12 @@
1
1
  "use client";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const require_chunk = require("../chunk-DY84GLCh.cjs");
4
+ const require_hooks_use_chart_zoom = require("../hooks/use-chart-zoom.cjs");
5
+ const require_hooks_use_reduced_motion = require("../hooks/use-reduced-motion.cjs");
4
6
  const require_utils_format = require("../utils/format.cjs");
5
7
  const require_utils_chart_scale = require("../utils/chart-scale.cjs");
6
8
  const require_utils_chart_time_ticks = require("../utils/chart-time-ticks.cjs");
7
- const require_hooks_use_reduced_motion = require("../hooks/use-reduced-motion.cjs");
8
9
  const require_components_chart = require("./chart.cjs");
9
- const require_hooks_use_chart_zoom = require("../hooks/use-chart-zoom.cjs");
10
10
  let react = require("react");
11
11
  react = require_chunk.__toESM(react);
12
12
  let react_jsx_runtime = require("react/jsx-runtime");
@@ -17,7 +17,7 @@ let _visx_shape = require("@visx/shape");
17
17
  let _visx_curve = require("@visx/curve");
18
18
  let _visx_tooltip = require("@visx/tooltip");
19
19
  let _visx_vendor_d3_array = require("@visx/vendor/d3-array");
20
- let cnfast = require("cnfast");
20
+ let cn = require("cn");
21
21
  //#region src/components/line-chart.tsx
22
22
  const DEFAULT_MARGIN = {
23
23
  top: 16,
@@ -69,7 +69,7 @@ function nearestDatum(data, date) {
69
69
  if (!d1) return d0;
70
70
  return date.valueOf() - d0.date.valueOf() > d1.date.valueOf() - date.valueOf() ? d1 : d0;
71
71
  }
72
- const defaultFormatDate = (date) => date.toLocaleDateString(void 0, {
72
+ const defaultFormatDate = (date) => date.toLocaleDateString(require_utils_format.getDocumentLang(), {
73
73
  month: "short",
74
74
  day: "numeric"
75
75
  });
@@ -241,7 +241,7 @@ const LineChart = ({ series, width, height, margin = DEFAULT_MARGIN, curve: defa
241
241
  });
242
242
  if (width < 10 || height < 10) return null;
243
243
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
244
- className: (0, cnfast.cn)("relative", className),
244
+ className: (0, cn.cn)("relative", className),
245
245
  children: [
246
246
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
247
247
  className: "block",
@@ -346,7 +346,7 @@ const LineChart = ({ series, width, height, margin = DEFAULT_MARGIN, curve: defa
346
346
  clipPath: `url(#${plotClipId})`,
347
347
  "data-testid": "chart-plot-clip",
348
348
  children: series.map((s, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_visx_shape.LinePath, {
349
- className: (0, cnfast.cn)(LINE_COLORS[i % LINE_COLORS.length], s.className),
349
+ className: (0, cn.cn)(LINE_COLORS[i % LINE_COLORS.length], s.className),
350
350
  curve: resolveCurve(s.curve ?? defaultCurve),
351
351
  data: s.data,
352
352
  fill: "none",
@@ -477,7 +477,7 @@ const LineChart = ({ series, width, height, margin = DEFAULT_MARGIN, curve: defa
477
477
  const d = nearestDatum(s.data, tooltipData.date);
478
478
  if (!d || !withinDomain(s.data, tooltipData.date)) return null;
479
479
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
480
- className: s.color ? void 0 : (0, cnfast.cn)(DOT_COLORS[i % DOT_COLORS.length]),
480
+ className: s.color ? void 0 : (0, cn.cn)(DOT_COLORS[i % DOT_COLORS.length]),
481
481
  cx: xScale(d.date),
482
482
  cy: yScale(d.value),
483
483
  fill: s.color,
@@ -1 +1 @@
1
- {"version":3,"file":"line-chart.cjs","names":["curveMonotoneX","curveStep","curveStepAfter","curveStepBefore","curveLinear","localeNumberFormat","formatYAxisTick","React","useChartZoom","useReducedMotion","buildYAxisScale","useAnimatedChartDomain","buildTimeTicks","useMeasuredSize","clampTooltipPosition","Group","LinePath","ChartZoomResetButton","ChartTooltipCard"],"sources":["../../src/components/line-chart.tsx"],"sourcesContent":["import {\n curveLinear,\n curveMonotoneX,\n curveStep,\n curveStepAfter,\n curveStepBefore,\n} from '@visx/curve'\nimport { localPoint } from '@visx/event'\nimport { Group } from '@visx/group'\nimport { scaleLinear, scaleTime } from '@visx/scale'\nimport { LinePath } from '@visx/shape'\nimport { useTooltip } from '@visx/tooltip'\nimport { bisector, extent } from '@visx/vendor/d3-array'\nimport * as React from 'react'\nimport { useCallback, useMemo } from 'react'\nimport { useAnimatedChartDomain, useChartZoom } from '../hooks/use-chart-zoom'\nimport { useReducedMotion } from '../hooks/use-reduced-motion'\nimport { buildYAxisScale, formatYAxisTick } from '../utils/chart-scale'\nimport { buildTimeTicks } from '../utils/chart-time-ticks'\nimport type { TimeDomain } from '../utils/chart-zoom'\nimport { cn } from '../utils/cn'\nimport { localeNumberFormat } from '../utils/format'\nimport {\n ChartTooltipCard,\n type ChartTooltipRow,\n ChartZoomResetButton,\n clampTooltipPosition,\n useMeasuredSize,\n} from './chart'\n\nexport interface LineChartDatum {\n date: Date\n value: number\n}\n\nexport type LineChartCurve =\n | 'monotone'\n | 'step'\n | 'step-after'\n | 'step-before'\n | 'linear'\n\nexport interface LineChartSeries {\n id: string\n data: LineChartDatum[]\n /** Label shown in the hover tooltip. Defaults to `id`. */\n label?: React.ReactNode\n className?: string\n /**\n * CSS color for the tooltip swatch and hover dot (e.g. `var(--orange-9)`).\n * Defaults to the palette color for the series index. Set this whenever\n * `className` overrides the stroke so the tooltip stays in sync.\n */\n color?: string\n /** Curve interpolation type. Default: inherits from LineChartProps.curve */\n curve?: LineChartCurve\n /** Render as a dashed line */\n dashed?: boolean\n /** Custom dash pattern (e.g. \"8,4\" or \"4,2,1,2\"). Only applies when dashed is true. */\n dashPattern?: string\n}\n\nexport interface LineChartProps {\n series: LineChartSeries[]\n width: number\n height: number\n margin?: { top: number; right: number; bottom: number; left: number }\n /** Default curve for all series. Default: 'monotone' */\n curve?: LineChartCurve\n showGrid?: boolean\n showTooltip?: boolean\n className?: string\n xTickCount?: number\n yTickCount?: number\n /** Fixes the y-axis to an explicit `[min, max]`. Defaults to the data extent. */\n yDomain?: [number, number]\n /** Formats the x-axis tick labels. */\n formatDate?: (date: Date) => string\n /** Formats the tooltip title. Defaults to `formatDate`. */\n formatTooltipDate?: (date: Date) => string\n formatValue?: (value: number) => string\n /**\n * Unit shown once at the top of the y-axis (e.g. \"kW\"). When set, y-axis tick\n * labels render as plain numbers (matching BarChart / PowerHistoryChart)\n * instead of repeating `formatValue` on every tick. `formatValue` still feeds\n * the tooltip. Omit to keep the per-tick `formatValue` labels.\n */\n yAxisUnit?: string\n /** Overrides the y-axis tick formatter used when `yAxisUnit` is set. Defaults to the shared compact formatter. */\n formatYTick?: (value: number) => string\n /**\n * Vertical reference markers positioned on the time axis (e.g. sunrise /\n * sunset). Each renders a dashed line across the plot with an optional label.\n */\n referenceLines?: Array<{ key: string; date: Date; label?: React.ReactNode }>\n /**\n * HTML content pinned to the top of the plot at a given time (e.g. an hourly\n * weather icon). Positioned by the same time scale as the series, so it lines\n * up with the curve below it.\n */\n topContent?: Array<{ key: string; date: Date; content: React.ReactNode }>\n zoomable?: boolean\n zoomResetLabel?: string\n zoomDomain?: [Date, Date] | null\n onZoomDomainChange?: (domain: [Date, Date] | null) => void\n}\n\nconst DEFAULT_MARGIN = { top: 16, right: 16, bottom: 40, left: 48 }\nconst DETAILED_X_AXIS_THRESHOLD = 6 * 60 * 60 * 1000\n\nconst CURVE_MAP = {\n monotone: curveMonotoneX,\n step: curveStep,\n 'step-after': curveStepAfter,\n 'step-before': curveStepBefore,\n linear: curveLinear,\n} as const\n\nconst resolveCurve = (type: LineChartCurve) => CURVE_MAP[type]\n\nconst dateBisector = bisector<LineChartDatum, Date>((d) => d.date)\nconst bisectDate = (data: LineChartDatum[], x: Date, lo?: number) =>\n dateBisector.left(data, x, lo)\n\n/** Whether `date` falls within a series' own x-range (data is sorted ascending). */\nfunction withinDomain(data: LineChartDatum[], date: Date): boolean {\n const first = data[0]\n const last = data[data.length - 1]\n if (!first || !last) return false\n const t = date.valueOf()\n return t >= first.date.valueOf() && t <= last.date.valueOf()\n}\n\n/**\n * y-domain padded 10% beyond the data extent. The baseline is pinned to 0 so\n * all-positive series render from the axis up; a series that dips below 0\n * (signed grid / battery power) extends the domain downward to keep the zero\n * crossing visible.\n */\nfunction computeYDomain(data: LineChartDatum[]): [number, number] {\n let min = 0\n let max = 0\n for (const d of data) {\n if (d.value < min) min = d.value\n if (d.value > max) max = d.value\n }\n if (min === max) return [min, min + 1]\n return [min * 1.1, max * 1.1]\n}\n\nfunction nearestDatum(\n data: LineChartDatum[],\n date: Date,\n): LineChartDatum | undefined {\n if (data.length === 0) return undefined\n const index = bisectDate(data, date, 1)\n const d0 = data[index - 1]\n const d1 = data[index]\n if (!d0) return d1\n if (!d1) return d0\n return date.valueOf() - d0.date.valueOf() > d1.date.valueOf() - date.valueOf()\n ? d1\n : d0\n}\n\nconst defaultFormatDate = (date: Date) =>\n date.toLocaleDateString(undefined, { month: 'short', day: 'numeric' })\n\nconst defaultValueFormat = localeNumberFormat()\nconst defaultFormatValue = (value: number) => defaultValueFormat.format(value)\n\nconst LINE_COLORS = [\n 'stroke-spark-9',\n 'stroke-green-9',\n 'stroke-blue-9',\n 'stroke-orange-9',\n 'stroke-red-9',\n]\n\nconst DOT_COLORS = [\n 'fill-spark-9',\n 'fill-green-9',\n 'fill-blue-9',\n 'fill-orange-9',\n 'fill-red-9',\n]\n\n// CSS-var colours matching LINE_COLORS, used for the tooltip legend dots.\nconst LEGEND_COLORS = [\n 'var(--spark-9)',\n 'var(--green-9)',\n 'var(--blue-9)',\n 'var(--orange-9)',\n 'var(--red-9)',\n]\n\nfunction toTimeDomain(dates: [Date, Date]): TimeDomain {\n return [dates[0].valueOf(), dates[1].valueOf()]\n}\n\nfunction fromTimeDomain(domain: TimeDomain): [Date, Date] {\n return [new Date(domain[0]), new Date(domain[1])]\n}\n\nfunction touchDistance(a: React.Touch, b: React.Touch): number {\n return Math.hypot(a.clientX - b.clientX, a.clientY - b.clientY)\n}\n\nfunction touchMidpoint(\n a: React.Touch,\n b: React.Touch,\n): {\n clientX: number\n clientY: number\n} {\n return {\n clientX: (a.clientX + b.clientX) / 2,\n clientY: (a.clientY + b.clientY) / 2,\n }\n}\n\nconst LineChart: React.FC<LineChartProps> = ({\n series,\n width,\n height,\n margin = DEFAULT_MARGIN,\n curve: defaultCurve = 'monotone',\n showGrid = true,\n showTooltip: enableTooltip = true,\n className,\n xTickCount = 5,\n yTickCount = 4,\n formatDate = defaultFormatDate,\n formatTooltipDate,\n formatValue = defaultFormatValue,\n yAxisUnit,\n formatYTick = formatYAxisTick,\n yDomain,\n referenceLines,\n topContent,\n zoomable = false,\n zoomResetLabel,\n zoomDomain: zoomDomainProp,\n onZoomDomainChange,\n}) => {\n const plotClipId = React.useId()\n const {\n showTooltip,\n hideTooltip,\n tooltipData,\n tooltipLeft,\n tooltipTop,\n tooltipOpen,\n } = useTooltip<{ date: Date }>()\n\n const innerWidth = Math.max(0, width - margin.left - margin.right)\n const innerHeight = Math.max(0, height - margin.top - margin.bottom)\n\n const allData = useMemo(() => series.flatMap((s) => s.data), [series])\n\n const fullDomain = useMemo((): TimeDomain | null => {\n const ext = extent(allData, (d) => d.date.valueOf())\n if (ext[0] == null || ext[1] == null) return null\n return [ext[0], ext[1]]\n }, [allData])\n\n const controlledZoomDomain =\n zoomDomainProp === undefined\n ? undefined\n : zoomDomainProp == null\n ? null\n : toTimeDomain(zoomDomainProp)\n\n const handleZoomDomainChange = useCallback(\n (domain: TimeDomain | null) => {\n onZoomDomainChange?.(domain ? fromTimeDomain(domain) : null)\n },\n [onZoomDomainChange],\n )\n\n const zoom = useChartZoom({\n enabled: zoomable,\n fullDomain,\n zoomDomain: controlledZoomDomain,\n onZoomDomainChange: handleZoomDomainChange,\n })\n\n const xDomain = useMemo((): [Date, Date] => {\n if (zoom.zoomWindow) return fromTimeDomain(zoom.zoomWindow)\n const ext = extent(allData, (d) => d.date) as\n | [Date, Date]\n | [undefined, undefined]\n if (ext[0] && ext[1]) return [ext[0], ext[1]]\n const now = new Date()\n return [now, now]\n }, [allData, zoom.zoomWindow])\n\n const xScale = useMemo(\n () =>\n scaleTime({\n range: [0, innerWidth],\n domain: xDomain,\n }),\n [innerWidth, xDomain],\n )\n\n const visibleData = useMemo(() => {\n const [start, end] = xDomain\n const t0 = start.valueOf()\n const t1 = end.valueOf()\n return allData.filter((d) => {\n const t = d.date.valueOf()\n return t >= t0 && t <= t1\n })\n }, [allData, xDomain])\n\n const reducedMotion = useReducedMotion()\n\n // With a unit, the y-axis is generated by the shared scale util (nice ticks\n // + rounded bounds) so it matches BarChart / PowerHistoryChart exactly.\n const yAxisScale = useMemo(() => {\n if (yAxisUnit === undefined) return null\n let min = 0\n let max = 0\n for (const d of visibleData) {\n if (d.value < min) min = d.value\n if (d.value > max) max = d.value\n }\n return buildYAxisScale(min, max)\n }, [visibleData, yAxisUnit])\n\n const targetYDomain = useMemo((): TimeDomain => {\n if (yDomain) return yDomain\n if (yAxisScale) return [yAxisScale.min, yAxisScale.max]\n return scaleLinear({\n domain: computeYDomain(visibleData),\n nice: true,\n }).domain() as [number, number]\n }, [visibleData, yAxisScale, yDomain])\n\n const displayedYDomain = useAnimatedChartDomain(targetYDomain, {\n animateChanges: zoom.isPinching,\n reducedMotion,\n })\n\n const yScale = useMemo(\n () =>\n scaleLinear({\n range: [innerHeight, 0],\n domain: [displayedYDomain[0], displayedYDomain[1]],\n }),\n [displayedYDomain, innerHeight],\n )\n\n const xTicks = zoom.isZoomed\n ? buildTimeTicks(\n xDomain[0].valueOf(),\n xDomain[1].valueOf(),\n xTickCount,\n ).map((tick) => new Date(tick))\n : xScale.ticks(xTickCount)\n const yTicks = yAxisScale ? yAxisScale.ticks : yScale.ticks(yTickCount)\n const formatAxisDate =\n zoom.isZoomed &&\n xDomain[1].valueOf() - xDomain[0].valueOf() <= DETAILED_X_AXIS_THRESHOLD\n ? (formatTooltipDate ?? formatDate)\n : formatDate\n\n const domainXFromEvent = useCallback(\n (\n event:\n | React.MouseEvent<SVGRectElement>\n | React.PointerEvent<SVGRectElement>\n | React.TouchEvent<SVGRectElement>,\n ) => {\n const point = localPoint(event)\n if (!point) return null\n return xScale.invert(point.x - margin.left).valueOf()\n },\n [margin.left, xScale],\n )\n\n const handleTooltip = useCallback(\n (\n event:\n | React.TouchEvent<SVGRectElement>\n | React.MouseEvent<SVGRectElement>,\n ) => {\n if (!enableTooltip || zoom.isBrushing || zoom.isPanning) return\n\n const point = localPoint(event)\n if (!point) return\n\n const x0 = xScale.invert(point.x - margin.left)\n\n // Snap to the data point closest to the cursor across all series, so the\n // cursor line + tooltip line up with real values.\n let anchorDate: Date | null = null\n let bestDistance = Infinity\n for (const s of series) {\n const d = nearestDatum(s.data, x0)\n if (!d) continue\n const distance = Math.abs(d.date.valueOf() - x0.valueOf())\n if (distance < bestDistance) {\n bestDistance = distance\n anchorDate = d.date\n }\n }\n\n if (!anchorDate) return\n\n showTooltip({\n tooltipData: { date: anchorDate },\n tooltipLeft: xScale(anchorDate) + margin.left,\n tooltipTop: margin.top,\n })\n },\n [\n enableTooltip,\n margin,\n series,\n showTooltip,\n xScale,\n zoom.isBrushing,\n zoom.isPanning,\n ],\n )\n\n const tooltipRows: ChartTooltipRow[] = tooltipData\n ? series.flatMap((s, i) => {\n const d = nearestDatum(s.data, tooltipData.date)\n if (!d || !withinDomain(s.data, tooltipData.date)) return []\n return [\n {\n key: s.id,\n label: s.label ?? s.id,\n color:\n s.color ?? (LEGEND_COLORS[i % LEGEND_COLORS.length] as string),\n value: formatValue(d.value),\n marker: s.dashed ? ('dashed-line' as const) : ('dot' as const),\n },\n ]\n })\n : []\n\n const [tooltipRef, tooltipSize] = useMeasuredSize<HTMLDivElement>()\n const tooltipPos = clampTooltipPosition({\n anchorX: tooltipLeft ?? 0,\n anchorY: tooltipTop ?? margin.top,\n width,\n height,\n tipWidth: tooltipSize.width,\n tipHeight: tooltipSize.height,\n placement: 'beside',\n })\n\n if (width < 10 || height < 10) return null\n\n return (\n <div className={cn('relative', className)}>\n <svg className=\"block\" height={height} width={width}>\n <defs>\n <clipPath id={plotClipId}>\n <rect height={innerHeight} width={innerWidth} x={0} y={0} />\n </clipPath>\n </defs>\n <Group left={margin.left} top={margin.top}>\n {/* Grid lines */}\n {showGrid &&\n yTicks.map((tick) => (\n <line\n className=\"stroke-gray-a4\"\n key={`grid-y-${tick}`}\n strokeDasharray=\"4,4\"\n x1={0}\n x2={innerWidth}\n y1={yScale(tick)}\n y2={yScale(tick)}\n />\n ))}\n\n {/* X axis */}\n <line\n className=\"stroke-gray-a6\"\n x1={0}\n x2={innerWidth}\n y1={innerHeight}\n y2={innerHeight}\n />\n\n {/* Reference markers (e.g. sunrise / sunset) */}\n {referenceLines?.map((ref) => {\n const x = xScale(ref.date)\n if (!Number.isFinite(x) || x < 0 || x > innerWidth) return null\n // Sit the label beside the line, on whichever side keeps it in\n // frame: right of a left-half marker, left of a right-half one.\n const anchorEnd = x > innerWidth / 2\n return (\n <g key={ref.key} pointerEvents=\"none\">\n <line\n className=\"stroke-orange-8\"\n strokeDasharray=\"3,3\"\n x1={x}\n x2={x}\n y1={0}\n y2={innerHeight}\n />\n {ref.label != null && (\n <text\n className=\"fill-orange-11 text-[10px]\"\n dy=\"0.9em\"\n textAnchor={anchorEnd ? 'end' : 'start'}\n x={x + (anchorEnd ? -4 : 4)}\n y={0}\n >\n {ref.label}\n </text>\n )}\n </g>\n )\n })}\n\n {/* X axis labels */}\n {xTicks.map((tick, index) => (\n <text\n dy=\"1em\"\n fill=\"var(--neutral-a11)\"\n fontSize={10}\n key={`x-${tick.valueOf()}`}\n textAnchor={\n index === 0\n ? 'start'\n : index === xTicks.length - 1\n ? 'end'\n : 'middle'\n }\n x={xScale(tick)}\n y={innerHeight + 8}\n >\n {formatAxisDate(tick)}\n </text>\n ))}\n\n {/* Y axis. With `yAxisUnit`, matches BarChart: a vertical axis line,\n short tick marks, plain numeric ticks, and the unit as a bold\n top-left header (top tick hidden). Without it, ticks repeat\n `formatValue` and no axis line/marks are drawn. */}\n {yAxisUnit !== undefined && (\n <line\n stroke=\"var(--neutral-a6)\"\n strokeWidth={1}\n x1={0}\n x2={0}\n y1={0}\n y2={innerHeight}\n />\n )}\n {yTicks.map((tick) => {\n const y = yScale(tick)\n return (\n <g key={`y-${tick}`}>\n {yAxisUnit !== undefined && (\n <line\n stroke=\"var(--neutral-a8)\"\n strokeWidth={1}\n x1={-4}\n x2={0}\n y1={y}\n y2={y}\n />\n )}\n <text\n dy=\"0.32em\"\n fill=\"var(--neutral-a11)\"\n fontSize={10}\n textAnchor=\"end\"\n x={yAxisUnit !== undefined ? -7 : -4}\n y={y}\n >\n {yAxisUnit !== undefined\n ? formatYTick(tick)\n : formatValue(tick)}\n </text>\n </g>\n )\n })}\n {yAxisUnit !== undefined && (\n <text\n fill=\"var(--neutral-a11)\"\n fontSize={10}\n fontWeight={600}\n textAnchor=\"start\"\n x={-margin.left}\n y={-6}\n >\n {yAxisUnit}\n </text>\n )}\n\n <g clipPath={`url(#${plotClipId})`} data-testid=\"chart-plot-clip\">\n {series.map((s, i) => (\n <LinePath\n className={cn(LINE_COLORS[i % LINE_COLORS.length], s.className)}\n curve={resolveCurve(s.curve ?? defaultCurve)}\n data={s.data}\n fill=\"none\"\n key={s.id}\n strokeDasharray={\n s.dashed ? (s.dashPattern ?? '6,4') : undefined\n }\n strokeWidth={2}\n x={(d) => xScale(d.date)}\n y={(d) => yScale(d.value)}\n />\n ))}\n </g>\n\n {zoom.brushBand && (\n <rect\n data-testid=\"chart-brush-band\"\n fill=\"var(--spark-a4)\"\n height={innerHeight}\n pointerEvents=\"none\"\n width={Math.abs(\n xScale(new Date(zoom.brushBand[1])) -\n xScale(new Date(zoom.brushBand[0])),\n )}\n x={Math.min(\n xScale(new Date(zoom.brushBand[0])),\n xScale(new Date(zoom.brushBand[1])),\n )}\n y={0}\n />\n )}\n\n {(enableTooltip || zoomable) && (\n <rect\n fill=\"transparent\"\n height={innerHeight}\n style={zoomable ? { touchAction: 'pan-y' } : undefined}\n width={innerWidth}\n x={0}\n y={0}\n onMouseLeave={() => {\n if (!zoom.isBrushing) hideTooltip()\n }}\n onMouseMove={(event) => {\n if (zoom.isBrushing) {\n const domainX = domainXFromEvent(event)\n if (domainX != null) zoom.onPointerMove(domainX)\n return\n }\n handleTooltip(event)\n }}\n onPointerDown={(event) => {\n if (!zoomable || event.pointerType === 'touch') return\n if (event.button !== 0) return\n const domainX = domainXFromEvent(event)\n if (domainX == null) return\n event.currentTarget.setPointerCapture?.(event.pointerId)\n hideTooltip()\n zoom.onPointerDown(domainX)\n }}\n onPointerMove={(event) => {\n if (!zoomable) return\n const domainX = domainXFromEvent(event)\n if (domainX != null) zoom.onPointerMove(domainX)\n }}\n onPointerUp={(event) => {\n if (!zoomable) return\n const domainX = domainXFromEvent(event)\n if (domainX != null) zoom.onPointerUp(domainX)\n else zoom.onPointerCancel()\n }}\n onPointerCancel={() => {\n zoom.onPointerCancel()\n }}\n onDoubleClick={() => {\n if (zoomable) zoom.onDoubleClick()\n }}\n onTouchStart={(event) => {\n if (!zoomable) return\n if (event.touches.length === 2) {\n const [a, b] = [event.touches[0], event.touches[1]]\n if (!a || !b) return\n const point = localPoint(\n event.currentTarget,\n touchMidpoint(a, b) as MouseEvent,\n )\n if (!point) return\n const midpoint = Math.min(\n 1,\n Math.max(0, (point.x - margin.left) / innerWidth),\n )\n zoom.onPinchStart(touchDistance(a, b), midpoint)\n hideTooltip()\n return\n }\n if (event.touches.length === 1 && zoom.isZoomed) {\n const point = localPoint(event)\n if (!point) return\n zoom.onPanStart({\n x: (point.x - margin.left) / innerWidth,\n y: (point.y - margin.top) / innerHeight,\n })\n hideTooltip()\n }\n }}\n onTouchMove={(event) => {\n if (zoomable && event.touches.length === 2) {\n const [a, b] = [event.touches[0], event.touches[1]]\n if (!a || !b) return\n const point = localPoint(\n event.currentTarget,\n touchMidpoint(a, b) as MouseEvent,\n )\n if (!point) return\n const midpoint = Math.min(\n 1,\n Math.max(0, (point.x - margin.left) / innerWidth),\n )\n zoom.onPinchMove(touchDistance(a, b), midpoint)\n return\n }\n if (event.touches.length === 1 && zoom.isZoomed) {\n const point = localPoint(event)\n if (!point) return\n zoom.onPanMove({\n x: (point.x - margin.left) / innerWidth,\n y: (point.y - margin.top) / innerHeight,\n })\n return\n }\n if (event.touches.length === 1) handleTooltip(event)\n }}\n onTouchEnd={(event) => {\n if (zoomable && event.touches.length < 2) zoom.onPinchEnd()\n if (event.touches.length === 0) {\n if (zoomable) zoom.onPanEnd()\n if (zoomable) zoom.onTap()\n hideTooltip()\n }\n }}\n onTouchCancel={() => {\n zoom.onPinchEnd()\n zoom.onPanEnd()\n }}\n />\n )}\n\n {/* Cursor line + a dot per series */}\n {tooltipOpen &&\n tooltipData &&\n !zoom.isBrushing &&\n !zoom.isPanning && (\n <>\n <line\n className=\"stroke-gray-a6\"\n pointerEvents=\"none\"\n strokeDasharray=\"4,4\"\n x1={xScale(tooltipData.date)}\n x2={xScale(tooltipData.date)}\n y1={0}\n y2={innerHeight}\n />\n {series.map((s, i) => {\n const d = nearestDatum(s.data, tooltipData.date)\n if (!d || !withinDomain(s.data, tooltipData.date)) return null\n return (\n <circle\n key={s.id}\n className={\n s.color\n ? undefined\n : cn(DOT_COLORS[i % DOT_COLORS.length])\n }\n cx={xScale(d.date)}\n cy={yScale(d.value)}\n fill={s.color}\n pointerEvents=\"none\"\n r={4}\n stroke=\"white\"\n strokeWidth={2}\n />\n )\n })}\n </>\n )}\n </Group>\n </svg>\n\n {topContent && topContent.length > 0 && (\n <div\n className=\"pointer-events-none absolute overflow-hidden\"\n style={{\n height: margin.top,\n left: margin.left,\n top: 0,\n width: innerWidth,\n }}\n >\n {topContent.map((item) => {\n const x = xScale(item.date)\n if (!Number.isFinite(x) || x < 0 || x > innerWidth) return null\n return (\n <div\n key={item.key}\n className=\"absolute -translate-x-1/2\"\n style={{ left: x, top: 0 }}\n >\n {item.content}\n </div>\n )\n })}\n </div>\n )}\n\n {zoom.isZoomed && zoomResetLabel && (\n <ChartZoomResetButton label={zoomResetLabel} onReset={zoom.resetZoom} />\n )}\n\n <div\n ref={tooltipRef}\n className=\"pointer-events-none absolute z-10\"\n style={{\n left: tooltipPos.left,\n top: tooltipPos.top,\n opacity:\n tooltipOpen && tooltipData && !zoom.isPanning && !zoom.isBrushing\n ? 1\n : 0,\n transition: reducedMotion\n ? 'opacity 140ms ease-out'\n : 'left 140ms ease-out, top 140ms ease-out, opacity 140ms ease-out',\n }}\n >\n {tooltipData && (\n <ChartTooltipCard\n label={(formatTooltipDate ?? formatDate)(tooltipData.date)}\n rows={tooltipRows}\n />\n )}\n </div>\n </div>\n )\n}\n\nexport { LineChart }\n"],"mappings":"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"}
1
+ {"version":3,"file":"line-chart.cjs","names":["curveMonotoneX","curveStep","curveStepAfter","curveStepBefore","curveLinear","getDocumentLang","localeNumberFormat","formatYAxisTick","React","useChartZoom","useReducedMotion","buildYAxisScale","useAnimatedChartDomain","buildTimeTicks","useMeasuredSize","clampTooltipPosition","Group","LinePath","ChartZoomResetButton","ChartTooltipCard"],"sources":["../../src/components/line-chart.tsx"],"sourcesContent":["import {\n curveLinear,\n curveMonotoneX,\n curveStep,\n curveStepAfter,\n curveStepBefore,\n} from '@visx/curve'\nimport { localPoint } from '@visx/event'\nimport { Group } from '@visx/group'\nimport { scaleLinear, scaleTime } from '@visx/scale'\nimport { LinePath } from '@visx/shape'\nimport { useTooltip } from '@visx/tooltip'\nimport { bisector, extent } from '@visx/vendor/d3-array'\nimport * as React from 'react'\nimport { useCallback, useMemo } from 'react'\nimport { useAnimatedChartDomain, useChartZoom } from '../hooks/use-chart-zoom'\nimport { useReducedMotion } from '../hooks/use-reduced-motion'\nimport { buildYAxisScale, formatYAxisTick } from '../utils/chart-scale'\nimport { buildTimeTicks } from '../utils/chart-time-ticks'\nimport type { TimeDomain } from '../utils/chart-zoom'\nimport { cn } from '../utils/cn'\nimport { getDocumentLang, localeNumberFormat } from '../utils/format'\nimport {\n ChartTooltipCard,\n type ChartTooltipRow,\n ChartZoomResetButton,\n clampTooltipPosition,\n useMeasuredSize,\n} from './chart'\n\nexport interface LineChartDatum {\n date: Date\n value: number\n}\n\nexport type LineChartCurve =\n | 'monotone'\n | 'step'\n | 'step-after'\n | 'step-before'\n | 'linear'\n\nexport interface LineChartSeries {\n id: string\n data: LineChartDatum[]\n /** Label shown in the hover tooltip. Defaults to `id`. */\n label?: React.ReactNode\n className?: string\n /**\n * CSS color for the tooltip swatch and hover dot (e.g. `var(--orange-9)`).\n * Defaults to the palette color for the series index. Set this whenever\n * `className` overrides the stroke so the tooltip stays in sync.\n */\n color?: string\n /** Curve interpolation type. Default: inherits from LineChartProps.curve */\n curve?: LineChartCurve\n /** Render as a dashed line */\n dashed?: boolean\n /** Custom dash pattern (e.g. \"8,4\" or \"4,2,1,2\"). Only applies when dashed is true. */\n dashPattern?: string\n}\n\nexport interface LineChartProps {\n series: LineChartSeries[]\n width: number\n height: number\n margin?: { top: number; right: number; bottom: number; left: number }\n /** Default curve for all series. Default: 'monotone' */\n curve?: LineChartCurve\n showGrid?: boolean\n showTooltip?: boolean\n className?: string\n xTickCount?: number\n yTickCount?: number\n /** Fixes the y-axis to an explicit `[min, max]`. Defaults to the data extent. */\n yDomain?: [number, number]\n /** Formats the x-axis tick labels. */\n formatDate?: (date: Date) => string\n /** Formats the tooltip title. Defaults to `formatDate`. */\n formatTooltipDate?: (date: Date) => string\n formatValue?: (value: number) => string\n /**\n * Unit shown once at the top of the y-axis (e.g. \"kW\"). When set, y-axis tick\n * labels render as plain numbers (matching BarChart / PowerHistoryChart)\n * instead of repeating `formatValue` on every tick. `formatValue` still feeds\n * the tooltip. Omit to keep the per-tick `formatValue` labels.\n */\n yAxisUnit?: string\n /** Overrides the y-axis tick formatter used when `yAxisUnit` is set. Defaults to the shared compact formatter. */\n formatYTick?: (value: number) => string\n /**\n * Vertical reference markers positioned on the time axis (e.g. sunrise /\n * sunset). Each renders a dashed line across the plot with an optional label.\n */\n referenceLines?: Array<{ key: string; date: Date; label?: React.ReactNode }>\n /**\n * HTML content pinned to the top of the plot at a given time (e.g. an hourly\n * weather icon). Positioned by the same time scale as the series, so it lines\n * up with the curve below it.\n */\n topContent?: Array<{ key: string; date: Date; content: React.ReactNode }>\n zoomable?: boolean\n zoomResetLabel?: string\n zoomDomain?: [Date, Date] | null\n onZoomDomainChange?: (domain: [Date, Date] | null) => void\n}\n\nconst DEFAULT_MARGIN = { top: 16, right: 16, bottom: 40, left: 48 }\nconst DETAILED_X_AXIS_THRESHOLD = 6 * 60 * 60 * 1000\n\nconst CURVE_MAP = {\n monotone: curveMonotoneX,\n step: curveStep,\n 'step-after': curveStepAfter,\n 'step-before': curveStepBefore,\n linear: curveLinear,\n} as const\n\nconst resolveCurve = (type: LineChartCurve) => CURVE_MAP[type]\n\nconst dateBisector = bisector<LineChartDatum, Date>((d) => d.date)\nconst bisectDate = (data: LineChartDatum[], x: Date, lo?: number) =>\n dateBisector.left(data, x, lo)\n\n/** Whether `date` falls within a series' own x-range (data is sorted ascending). */\nfunction withinDomain(data: LineChartDatum[], date: Date): boolean {\n const first = data[0]\n const last = data[data.length - 1]\n if (!first || !last) return false\n const t = date.valueOf()\n return t >= first.date.valueOf() && t <= last.date.valueOf()\n}\n\n/**\n * y-domain padded 10% beyond the data extent. The baseline is pinned to 0 so\n * all-positive series render from the axis up; a series that dips below 0\n * (signed grid / battery power) extends the domain downward to keep the zero\n * crossing visible.\n */\nfunction computeYDomain(data: LineChartDatum[]): [number, number] {\n let min = 0\n let max = 0\n for (const d of data) {\n if (d.value < min) min = d.value\n if (d.value > max) max = d.value\n }\n if (min === max) return [min, min + 1]\n return [min * 1.1, max * 1.1]\n}\n\nfunction nearestDatum(\n data: LineChartDatum[],\n date: Date,\n): LineChartDatum | undefined {\n if (data.length === 0) return undefined\n const index = bisectDate(data, date, 1)\n const d0 = data[index - 1]\n const d1 = data[index]\n if (!d0) return d1\n if (!d1) return d0\n return date.valueOf() - d0.date.valueOf() > d1.date.valueOf() - date.valueOf()\n ? d1\n : d0\n}\n\nconst defaultFormatDate = (date: Date) =>\n date.toLocaleDateString(getDocumentLang(), { month: 'short', day: 'numeric' })\n\nconst defaultValueFormat = localeNumberFormat()\nconst defaultFormatValue = (value: number) => defaultValueFormat.format(value)\n\nconst LINE_COLORS = [\n 'stroke-spark-9',\n 'stroke-green-9',\n 'stroke-blue-9',\n 'stroke-orange-9',\n 'stroke-red-9',\n]\n\nconst DOT_COLORS = [\n 'fill-spark-9',\n 'fill-green-9',\n 'fill-blue-9',\n 'fill-orange-9',\n 'fill-red-9',\n]\n\n// CSS-var colours matching LINE_COLORS, used for the tooltip legend dots.\nconst LEGEND_COLORS = [\n 'var(--spark-9)',\n 'var(--green-9)',\n 'var(--blue-9)',\n 'var(--orange-9)',\n 'var(--red-9)',\n]\n\nfunction toTimeDomain(dates: [Date, Date]): TimeDomain {\n return [dates[0].valueOf(), dates[1].valueOf()]\n}\n\nfunction fromTimeDomain(domain: TimeDomain): [Date, Date] {\n return [new Date(domain[0]), new Date(domain[1])]\n}\n\nfunction touchDistance(a: React.Touch, b: React.Touch): number {\n return Math.hypot(a.clientX - b.clientX, a.clientY - b.clientY)\n}\n\nfunction touchMidpoint(\n a: React.Touch,\n b: React.Touch,\n): {\n clientX: number\n clientY: number\n} {\n return {\n clientX: (a.clientX + b.clientX) / 2,\n clientY: (a.clientY + b.clientY) / 2,\n }\n}\n\n// oxlint-disable-next-line eslint/complexity -- pre-existing; split it before adding branches\nconst LineChart: React.FC<LineChartProps> = ({\n series,\n width,\n height,\n margin = DEFAULT_MARGIN,\n curve: defaultCurve = 'monotone',\n showGrid = true,\n showTooltip: enableTooltip = true,\n className,\n xTickCount = 5,\n yTickCount = 4,\n formatDate = defaultFormatDate,\n formatTooltipDate,\n formatValue = defaultFormatValue,\n yAxisUnit,\n formatYTick = formatYAxisTick,\n yDomain,\n referenceLines,\n topContent,\n zoomable = false,\n zoomResetLabel,\n zoomDomain: zoomDomainProp,\n onZoomDomainChange,\n}) => {\n const plotClipId = React.useId()\n const {\n showTooltip,\n hideTooltip,\n tooltipData,\n tooltipLeft,\n tooltipTop,\n tooltipOpen,\n } = useTooltip<{ date: Date }>()\n\n const innerWidth = Math.max(0, width - margin.left - margin.right)\n const innerHeight = Math.max(0, height - margin.top - margin.bottom)\n\n const allData = useMemo(() => series.flatMap((s) => s.data), [series])\n\n const fullDomain = useMemo((): TimeDomain | null => {\n const ext = extent(allData, (d) => d.date.valueOf())\n if (ext[0] == null || ext[1] == null) return null\n return [ext[0], ext[1]]\n }, [allData])\n\n const controlledZoomDomain =\n zoomDomainProp === undefined\n ? undefined\n : zoomDomainProp == null\n ? null\n : toTimeDomain(zoomDomainProp)\n\n const handleZoomDomainChange = useCallback(\n (domain: TimeDomain | null) => {\n onZoomDomainChange?.(domain ? fromTimeDomain(domain) : null)\n },\n [onZoomDomainChange],\n )\n\n const zoom = useChartZoom({\n enabled: zoomable,\n fullDomain,\n zoomDomain: controlledZoomDomain,\n onZoomDomainChange: handleZoomDomainChange,\n })\n\n const xDomain = useMemo((): [Date, Date] => {\n if (zoom.zoomWindow) return fromTimeDomain(zoom.zoomWindow)\n const ext = extent(allData, (d) => d.date) as\n | [Date, Date]\n | [undefined, undefined]\n if (ext[0] && ext[1]) return [ext[0], ext[1]]\n const now = new Date()\n return [now, now]\n }, [allData, zoom.zoomWindow])\n\n const xScale = useMemo(\n () =>\n scaleTime({\n range: [0, innerWidth],\n domain: xDomain,\n }),\n [innerWidth, xDomain],\n )\n\n const visibleData = useMemo(() => {\n const [start, end] = xDomain\n const t0 = start.valueOf()\n const t1 = end.valueOf()\n return allData.filter((d) => {\n const t = d.date.valueOf()\n return t >= t0 && t <= t1\n })\n }, [allData, xDomain])\n\n const reducedMotion = useReducedMotion()\n\n // With a unit, the y-axis is generated by the shared scale util (nice ticks\n // + rounded bounds) so it matches BarChart / PowerHistoryChart exactly.\n const yAxisScale = useMemo(() => {\n if (yAxisUnit === undefined) return null\n let min = 0\n let max = 0\n for (const d of visibleData) {\n if (d.value < min) min = d.value\n if (d.value > max) max = d.value\n }\n return buildYAxisScale(min, max)\n }, [visibleData, yAxisUnit])\n\n const targetYDomain = useMemo((): TimeDomain => {\n if (yDomain) return yDomain\n if (yAxisScale) return [yAxisScale.min, yAxisScale.max]\n return scaleLinear({\n domain: computeYDomain(visibleData),\n nice: true,\n }).domain() as [number, number]\n }, [visibleData, yAxisScale, yDomain])\n\n const displayedYDomain = useAnimatedChartDomain(targetYDomain, {\n animateChanges: zoom.isPinching,\n reducedMotion,\n })\n\n const yScale = useMemo(\n () =>\n scaleLinear({\n range: [innerHeight, 0],\n domain: [displayedYDomain[0], displayedYDomain[1]],\n }),\n [displayedYDomain, innerHeight],\n )\n\n const xTicks = zoom.isZoomed\n ? buildTimeTicks(\n xDomain[0].valueOf(),\n xDomain[1].valueOf(),\n xTickCount,\n ).map((tick) => new Date(tick))\n : xScale.ticks(xTickCount)\n const yTicks = yAxisScale ? yAxisScale.ticks : yScale.ticks(yTickCount)\n const formatAxisDate =\n zoom.isZoomed &&\n xDomain[1].valueOf() - xDomain[0].valueOf() <= DETAILED_X_AXIS_THRESHOLD\n ? (formatTooltipDate ?? formatDate)\n : formatDate\n\n const domainXFromEvent = useCallback(\n (\n event:\n | React.MouseEvent<SVGRectElement>\n | React.PointerEvent<SVGRectElement>\n | React.TouchEvent<SVGRectElement>,\n ) => {\n const point = localPoint(event)\n if (!point) return null\n return xScale.invert(point.x - margin.left).valueOf()\n },\n [margin.left, xScale],\n )\n\n const handleTooltip = useCallback(\n (\n event:\n | React.TouchEvent<SVGRectElement>\n | React.MouseEvent<SVGRectElement>,\n ) => {\n if (!enableTooltip || zoom.isBrushing || zoom.isPanning) return\n\n const point = localPoint(event)\n if (!point) return\n\n const x0 = xScale.invert(point.x - margin.left)\n\n // Snap to the data point closest to the cursor across all series, so the\n // cursor line + tooltip line up with real values.\n let anchorDate: Date | null = null\n let bestDistance = Infinity\n for (const s of series) {\n const d = nearestDatum(s.data, x0)\n if (!d) continue\n const distance = Math.abs(d.date.valueOf() - x0.valueOf())\n if (distance < bestDistance) {\n bestDistance = distance\n anchorDate = d.date\n }\n }\n\n if (!anchorDate) return\n\n showTooltip({\n tooltipData: { date: anchorDate },\n tooltipLeft: xScale(anchorDate) + margin.left,\n tooltipTop: margin.top,\n })\n },\n [\n enableTooltip,\n margin,\n series,\n showTooltip,\n xScale,\n zoom.isBrushing,\n zoom.isPanning,\n ],\n )\n\n const tooltipRows: ChartTooltipRow[] = tooltipData\n ? series.flatMap((s, i) => {\n const d = nearestDatum(s.data, tooltipData.date)\n if (!d || !withinDomain(s.data, tooltipData.date)) return []\n return [\n {\n key: s.id,\n label: s.label ?? s.id,\n color:\n s.color ?? (LEGEND_COLORS[i % LEGEND_COLORS.length] as string),\n value: formatValue(d.value),\n marker: s.dashed ? ('dashed-line' as const) : ('dot' as const),\n },\n ]\n })\n : []\n\n const [tooltipRef, tooltipSize] = useMeasuredSize<HTMLDivElement>()\n const tooltipPos = clampTooltipPosition({\n anchorX: tooltipLeft ?? 0,\n anchorY: tooltipTop ?? margin.top,\n width,\n height,\n tipWidth: tooltipSize.width,\n tipHeight: tooltipSize.height,\n placement: 'beside',\n })\n\n if (width < 10 || height < 10) return null\n\n return (\n <div className={cn('relative', className)}>\n <svg className=\"block\" height={height} width={width}>\n <defs>\n <clipPath id={plotClipId}>\n <rect height={innerHeight} width={innerWidth} x={0} y={0} />\n </clipPath>\n </defs>\n <Group left={margin.left} top={margin.top}>\n {/* Grid lines */}\n {showGrid &&\n yTicks.map((tick) => (\n <line\n className=\"stroke-gray-a4\"\n key={`grid-y-${tick}`}\n strokeDasharray=\"4,4\"\n x1={0}\n x2={innerWidth}\n y1={yScale(tick)}\n y2={yScale(tick)}\n />\n ))}\n\n {/* X axis */}\n <line\n className=\"stroke-gray-a6\"\n x1={0}\n x2={innerWidth}\n y1={innerHeight}\n y2={innerHeight}\n />\n\n {/* Reference markers (e.g. sunrise / sunset) */}\n {referenceLines?.map((ref) => {\n const x = xScale(ref.date)\n if (!Number.isFinite(x) || x < 0 || x > innerWidth) return null\n // Sit the label beside the line, on whichever side keeps it in\n // frame: right of a left-half marker, left of a right-half one.\n const anchorEnd = x > innerWidth / 2\n return (\n <g key={ref.key} pointerEvents=\"none\">\n <line\n className=\"stroke-orange-8\"\n strokeDasharray=\"3,3\"\n x1={x}\n x2={x}\n y1={0}\n y2={innerHeight}\n />\n {ref.label != null && (\n <text\n className=\"fill-orange-11 text-[10px]\"\n dy=\"0.9em\"\n textAnchor={anchorEnd ? 'end' : 'start'}\n x={x + (anchorEnd ? -4 : 4)}\n y={0}\n >\n {ref.label}\n </text>\n )}\n </g>\n )\n })}\n\n {/* X axis labels */}\n {xTicks.map((tick, index) => (\n <text\n dy=\"1em\"\n fill=\"var(--neutral-a11)\"\n fontSize={10}\n key={`x-${tick.valueOf()}`}\n textAnchor={\n index === 0\n ? 'start'\n : index === xTicks.length - 1\n ? 'end'\n : 'middle'\n }\n x={xScale(tick)}\n y={innerHeight + 8}\n >\n {formatAxisDate(tick)}\n </text>\n ))}\n\n {/* Y axis. With `yAxisUnit`, matches BarChart: a vertical axis line,\n short tick marks, plain numeric ticks, and the unit as a bold\n top-left header (top tick hidden). Without it, ticks repeat\n `formatValue` and no axis line/marks are drawn. */}\n {yAxisUnit !== undefined && (\n <line\n stroke=\"var(--neutral-a6)\"\n strokeWidth={1}\n x1={0}\n x2={0}\n y1={0}\n y2={innerHeight}\n />\n )}\n {yTicks.map((tick) => {\n const y = yScale(tick)\n return (\n <g key={`y-${tick}`}>\n {yAxisUnit !== undefined && (\n <line\n stroke=\"var(--neutral-a8)\"\n strokeWidth={1}\n x1={-4}\n x2={0}\n y1={y}\n y2={y}\n />\n )}\n <text\n dy=\"0.32em\"\n fill=\"var(--neutral-a11)\"\n fontSize={10}\n textAnchor=\"end\"\n x={yAxisUnit !== undefined ? -7 : -4}\n y={y}\n >\n {yAxisUnit !== undefined\n ? formatYTick(tick)\n : formatValue(tick)}\n </text>\n </g>\n )\n })}\n {yAxisUnit !== undefined && (\n <text\n fill=\"var(--neutral-a11)\"\n fontSize={10}\n fontWeight={600}\n textAnchor=\"start\"\n x={-margin.left}\n y={-6}\n >\n {yAxisUnit}\n </text>\n )}\n\n <g clipPath={`url(#${plotClipId})`} data-testid=\"chart-plot-clip\">\n {series.map((s, i) => (\n <LinePath\n className={cn(LINE_COLORS[i % LINE_COLORS.length], s.className)}\n curve={resolveCurve(s.curve ?? defaultCurve)}\n data={s.data}\n fill=\"none\"\n key={s.id}\n strokeDasharray={\n s.dashed ? (s.dashPattern ?? '6,4') : undefined\n }\n strokeWidth={2}\n x={(d) => xScale(d.date)}\n y={(d) => yScale(d.value)}\n />\n ))}\n </g>\n\n {zoom.brushBand && (\n <rect\n data-testid=\"chart-brush-band\"\n fill=\"var(--spark-a4)\"\n height={innerHeight}\n pointerEvents=\"none\"\n width={Math.abs(\n xScale(new Date(zoom.brushBand[1])) -\n xScale(new Date(zoom.brushBand[0])),\n )}\n x={Math.min(\n xScale(new Date(zoom.brushBand[0])),\n xScale(new Date(zoom.brushBand[1])),\n )}\n y={0}\n />\n )}\n\n {(enableTooltip || zoomable) && (\n <rect\n fill=\"transparent\"\n height={innerHeight}\n style={zoomable ? { touchAction: 'pan-y' } : undefined}\n width={innerWidth}\n x={0}\n y={0}\n onMouseLeave={() => {\n if (!zoom.isBrushing) hideTooltip()\n }}\n onMouseMove={(event) => {\n if (zoom.isBrushing) {\n const domainX = domainXFromEvent(event)\n if (domainX != null) zoom.onPointerMove(domainX)\n return\n }\n handleTooltip(event)\n }}\n onPointerDown={(event) => {\n if (!zoomable || event.pointerType === 'touch') return\n if (event.button !== 0) return\n const domainX = domainXFromEvent(event)\n if (domainX == null) return\n event.currentTarget.setPointerCapture?.(event.pointerId)\n hideTooltip()\n zoom.onPointerDown(domainX)\n }}\n onPointerMove={(event) => {\n if (!zoomable) return\n const domainX = domainXFromEvent(event)\n if (domainX != null) zoom.onPointerMove(domainX)\n }}\n onPointerUp={(event) => {\n if (!zoomable) return\n const domainX = domainXFromEvent(event)\n if (domainX != null) zoom.onPointerUp(domainX)\n else zoom.onPointerCancel()\n }}\n onPointerCancel={() => {\n zoom.onPointerCancel()\n }}\n onDoubleClick={() => {\n if (zoomable) zoom.onDoubleClick()\n }}\n onTouchStart={(event) => {\n if (!zoomable) return\n if (event.touches.length === 2) {\n const [a, b] = [event.touches[0], event.touches[1]]\n if (!a || !b) return\n const point = localPoint(\n event.currentTarget,\n touchMidpoint(a, b) as MouseEvent,\n )\n if (!point) return\n const midpoint = Math.min(\n 1,\n Math.max(0, (point.x - margin.left) / innerWidth),\n )\n zoom.onPinchStart(touchDistance(a, b), midpoint)\n hideTooltip()\n return\n }\n if (event.touches.length === 1 && zoom.isZoomed) {\n const point = localPoint(event)\n if (!point) return\n zoom.onPanStart({\n x: (point.x - margin.left) / innerWidth,\n y: (point.y - margin.top) / innerHeight,\n })\n hideTooltip()\n }\n }}\n onTouchMove={(event) => {\n if (zoomable && event.touches.length === 2) {\n const [a, b] = [event.touches[0], event.touches[1]]\n if (!a || !b) return\n const point = localPoint(\n event.currentTarget,\n touchMidpoint(a, b) as MouseEvent,\n )\n if (!point) return\n const midpoint = Math.min(\n 1,\n Math.max(0, (point.x - margin.left) / innerWidth),\n )\n zoom.onPinchMove(touchDistance(a, b), midpoint)\n return\n }\n if (event.touches.length === 1 && zoom.isZoomed) {\n const point = localPoint(event)\n if (!point) return\n zoom.onPanMove({\n x: (point.x - margin.left) / innerWidth,\n y: (point.y - margin.top) / innerHeight,\n })\n return\n }\n if (event.touches.length === 1) handleTooltip(event)\n }}\n onTouchEnd={(event) => {\n if (zoomable && event.touches.length < 2) zoom.onPinchEnd()\n if (event.touches.length === 0) {\n if (zoomable) zoom.onPanEnd()\n if (zoomable) zoom.onTap()\n hideTooltip()\n }\n }}\n onTouchCancel={() => {\n zoom.onPinchEnd()\n zoom.onPanEnd()\n }}\n />\n )}\n\n {/* Cursor line + a dot per series */}\n {tooltipOpen &&\n tooltipData &&\n !zoom.isBrushing &&\n !zoom.isPanning && (\n <>\n <line\n className=\"stroke-gray-a6\"\n pointerEvents=\"none\"\n strokeDasharray=\"4,4\"\n x1={xScale(tooltipData.date)}\n x2={xScale(tooltipData.date)}\n y1={0}\n y2={innerHeight}\n />\n {series.map((s, i) => {\n const d = nearestDatum(s.data, tooltipData.date)\n if (!d || !withinDomain(s.data, tooltipData.date)) return null\n return (\n <circle\n key={s.id}\n className={\n s.color\n ? undefined\n : cn(DOT_COLORS[i % DOT_COLORS.length])\n }\n cx={xScale(d.date)}\n cy={yScale(d.value)}\n fill={s.color}\n pointerEvents=\"none\"\n r={4}\n stroke=\"white\"\n strokeWidth={2}\n />\n )\n })}\n </>\n )}\n </Group>\n </svg>\n\n {topContent && topContent.length > 0 && (\n <div\n className=\"pointer-events-none absolute overflow-hidden\"\n style={{\n height: margin.top,\n left: margin.left,\n top: 0,\n width: innerWidth,\n }}\n >\n {topContent.map((item) => {\n const x = xScale(item.date)\n if (!Number.isFinite(x) || x < 0 || x > innerWidth) return null\n return (\n <div\n key={item.key}\n className=\"absolute -translate-x-1/2\"\n style={{ left: x, top: 0 }}\n >\n {item.content}\n </div>\n )\n })}\n </div>\n )}\n\n {zoom.isZoomed && zoomResetLabel && (\n <ChartZoomResetButton label={zoomResetLabel} onReset={zoom.resetZoom} />\n )}\n\n <div\n ref={tooltipRef}\n className=\"pointer-events-none absolute z-10\"\n style={{\n left: tooltipPos.left,\n top: tooltipPos.top,\n opacity:\n tooltipOpen && tooltipData && !zoom.isPanning && !zoom.isBrushing\n ? 1\n : 0,\n transition: reducedMotion\n ? 'opacity 140ms ease-out'\n : 'left 140ms ease-out, top 140ms ease-out, opacity 140ms ease-out',\n }}\n >\n {tooltipData && (\n <ChartTooltipCard\n label={(formatTooltipDate ?? formatDate)(tooltipData.date)}\n rows={tooltipRows}\n />\n )}\n </div>\n </div>\n )\n}\n\nexport { LineChart }\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA2GA,MAAM,iBAAiB;CAAE,KAAK;CAAI,OAAO;CAAI,QAAQ;CAAI,MAAM;AAAG;AAClE,MAAM,4BAA4B,MAAS,KAAK;AAEhD,MAAM,YAAY;CAChB,UAAUA,YAAAA;CACV,MAAMC,YAAAA;CACN,cAAcC,YAAAA;CACd,eAAeC,YAAAA;CACf,QAAQC,YAAAA;AACV;AAEA,MAAM,gBAAgB,SAAyB,UAAU;AAEzD,MAAM,gBAAA,GAAA,sBAAA,WAA+C,MAAM,EAAE,IAAI;AACjE,MAAM,cAAc,MAAwB,GAAS,OACnD,aAAa,KAAK,MAAM,GAAG,EAAE;;AAG/B,SAAS,aAAa,MAAwB,MAAqB;CACjE,MAAM,QAAQ,KAAK;CACnB,MAAM,OAAO,KAAK,KAAK,SAAS;CAChC,IAAI,CAAC,SAAS,CAAC,MAAM,OAAO;CAC5B,MAAM,IAAI,KAAK,QAAQ;CACvB,OAAO,KAAK,MAAM,KAAK,QAAQ,KAAK,KAAK,KAAK,KAAK,QAAQ;AAC7D;;;;;;;AAQA,SAAS,eAAe,MAA0C;CAChE,IAAI,MAAM;CACV,IAAI,MAAM;CACV,KAAK,MAAM,KAAK,MAAM;EACpB,IAAI,EAAE,QAAQ,KAAK,MAAM,EAAE;EAC3B,IAAI,EAAE,QAAQ,KAAK,MAAM,EAAE;CAC7B;CACA,IAAI,QAAQ,KAAK,OAAO,CAAC,KAAK,MAAM,CAAC;CACrC,OAAO,CAAC,MAAM,KAAK,MAAM,GAAG;AAC9B;AAEA,SAAS,aACP,MACA,MAC4B;CAC5B,IAAI,KAAK,WAAW,GAAG,OAAO,KAAA;CAC9B,MAAM,QAAQ,WAAW,MAAM,MAAM,CAAC;CACtC,MAAM,KAAK,KAAK,QAAQ;CACxB,MAAM,KAAK,KAAK;CAChB,IAAI,CAAC,IAAI,OAAO;CAChB,IAAI,CAAC,IAAI,OAAO;CAChB,OAAO,KAAK,QAAQ,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,QAAQ,IAAI,KAAK,QAAQ,IACzE,KACA;AACN;AAEA,MAAM,qBAAqB,SACzB,KAAK,mBAAmBC,qBAAAA,gBAAgB,GAAG;CAAE,OAAO;CAAS,KAAK;AAAU,CAAC;AAE/E,MAAM,qBAAqBC,qBAAAA,mBAAmB;AAC9C,MAAM,sBAAsB,UAAkB,mBAAmB,OAAO,KAAK;AAE7E,MAAM,cAAc;CAClB;CACA;CACA;CACA;CACA;AACF;AAEA,MAAM,aAAa;CACjB;CACA;CACA;CACA;CACA;AACF;AAGA,MAAM,gBAAgB;CACpB;CACA;CACA;CACA;CACA;AACF;AAEA,SAAS,aAAa,OAAiC;CACrD,OAAO,CAAC,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;AAChD;AAEA,SAAS,eAAe,QAAkC;CACxD,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE,GAAG,IAAI,KAAK,OAAO,EAAE,CAAC;AAClD;AAEA,SAAS,cAAc,GAAgB,GAAwB;CAC7D,OAAO,KAAK,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO;AAChE;AAEA,SAAS,cACP,GACA,GAIA;CACA,OAAO;EACL,UAAU,EAAE,UAAU,EAAE,WAAW;EACnC,UAAU,EAAE,UAAU,EAAE,WAAW;CACrC;AACF;AAGA,MAAM,aAAuC,EAC3C,QACA,OACA,QACA,SAAS,gBACT,OAAO,eAAe,YACtB,WAAW,MACX,aAAa,gBAAgB,MAC7B,WACA,aAAa,GACb,aAAa,GACb,aAAa,mBACb,mBACA,cAAc,oBACd,WACA,cAAcC,0BAAAA,iBACd,SACA,gBACA,YACA,WAAW,OACX,gBACA,YAAY,gBACZ,yBACI;CACJ,MAAM,aAAaC,MAAM,MAAM;CAC/B,MAAM,EACJ,aACA,aACA,aACA,aACA,YACA,iBAAA,GAAA,cAAA,YAC6B;CAE/B,MAAM,aAAa,KAAK,IAAI,GAAG,QAAQ,OAAO,OAAO,OAAO,KAAK;CACjE,MAAM,cAAc,KAAK,IAAI,GAAG,SAAS,OAAO,MAAM,OAAO,MAAM;CAEnE,MAAM,WAAA,GAAA,MAAA,eAAwB,OAAO,SAAS,MAAM,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC;CAsBrE,MAAM,OAAOC,6BAAAA,aAAa;EACxB,SAAS;EACT,aAAA,GAAA,MAAA,eAtBkD;GAClD,MAAM,OAAA,GAAA,sBAAA,QAAa,UAAU,MAAM,EAAE,KAAK,QAAQ,CAAC;GACnD,IAAI,IAAI,MAAM,QAAQ,IAAI,MAAM,MAAM,OAAO;GAC7C,OAAO,CAAC,IAAI,IAAI,IAAI,EAAE;EACxB,GAAG,CAAC,OAAO,CAkBA;EACT,YAhBA,mBAAmB,KAAA,IACf,KAAA,IACA,kBAAkB,OAChB,OACA,aAAa,cAAc;EAajC,qBAAA,GAAA,MAAA,cAVC,WAA8B;GAC7B,qBAAqB,SAAS,eAAe,MAAM,IAAI,IAAI;EAC7D,GACA,CAAC,kBAAkB,CAOsB;CAC3C,CAAC;CAED,MAAM,WAAA,GAAA,MAAA,eAAsC;EAC1C,IAAI,KAAK,YAAY,OAAO,eAAe,KAAK,UAAU;EAC1D,MAAM,OAAA,GAAA,sBAAA,QAAa,UAAU,MAAM,EAAE,IAAI;EAGzC,IAAI,IAAI,MAAM,IAAI,IAAI,OAAO,CAAC,IAAI,IAAI,IAAI,EAAE;EAC5C,MAAM,sBAAM,IAAI,KAAK;EACrB,OAAO,CAAC,KAAK,GAAG;CAClB,GAAG,CAAC,SAAS,KAAK,UAAU,CAAC;CAE7B,MAAM,UAAA,GAAA,MAAA,gBAAA,GAAA,YAAA,WAEQ;EACR,OAAO,CAAC,GAAG,UAAU;EACrB,QAAQ;CACV,CAAC,GACH,CAAC,YAAY,OAAO,CACtB;CAEA,MAAM,eAAA,GAAA,MAAA,eAA4B;EAChC,MAAM,CAAC,OAAO,OAAO;EACrB,MAAM,KAAK,MAAM,QAAQ;EACzB,MAAM,KAAK,IAAI,QAAQ;EACvB,OAAO,QAAQ,QAAQ,MAAM;GAC3B,MAAM,IAAI,EAAE,KAAK,QAAQ;GACzB,OAAO,KAAK,MAAM,KAAK;EACzB,CAAC;CACH,GAAG,CAAC,SAAS,OAAO,CAAC;CAErB,MAAM,gBAAgBC,iCAAAA,iBAAiB;CAIvC,MAAM,cAAA,GAAA,MAAA,eAA2B;EAC/B,IAAI,cAAc,KAAA,GAAW,OAAO;EACpC,IAAI,MAAM;EACV,IAAI,MAAM;EACV,KAAK,MAAM,KAAK,aAAa;GAC3B,IAAI,EAAE,QAAQ,KAAK,MAAM,EAAE;GAC3B,IAAI,EAAE,QAAQ,KAAK,MAAM,EAAE;EAC7B;EACA,OAAOC,0BAAAA,gBAAgB,KAAK,GAAG;CACjC,GAAG,CAAC,aAAa,SAAS,CAAC;CAW3B,MAAM,mBAAmBC,6BAAAA,wBAAAA,GAAAA,MAAAA,eATuB;EAC9C,IAAI,SAAS,OAAO;EACpB,IAAI,YAAY,OAAO,CAAC,WAAW,KAAK,WAAW,GAAG;EACtD,QAAA,GAAA,YAAA,aAAmB;GACjB,QAAQ,eAAe,WAAW;GAClC,MAAM;EACR,CAAC,EAAE,OAAO;CACZ,GAAG;EAAC;EAAa;EAAY;CAAO,CAEwB,GAAG;EAC7D,gBAAgB,KAAK;EACrB;CACF,CAAC;CAED,MAAM,UAAA,GAAA,MAAA,gBAAA,GAAA,YAAA,aAEU;EACV,OAAO,CAAC,aAAa,CAAC;EACtB,QAAQ,CAAC,iBAAiB,IAAI,iBAAiB,EAAE;CACnD,CAAC,GACH,CAAC,kBAAkB,WAAW,CAChC;CAEA,MAAM,SAAS,KAAK,WAChBC,+BAAAA,eACE,QAAQ,GAAG,QAAQ,GACnB,QAAQ,GAAG,QAAQ,GACnB,UACF,EAAE,KAAK,SAAS,IAAI,KAAK,IAAI,CAAC,IAC9B,OAAO,MAAM,UAAU;CAC3B,MAAM,SAAS,aAAa,WAAW,QAAQ,OAAO,MAAM,UAAU;CACtE,MAAM,iBACJ,KAAK,YACL,QAAQ,GAAG,QAAQ,IAAI,QAAQ,GAAG,QAAQ,KAAK,4BAC1C,qBAAqB,aACtB;CAEN,MAAM,oBAAA,GAAA,MAAA,cAEF,UAIG;EACH,MAAM,SAAA,GAAA,YAAA,YAAmB,KAAK;EAC9B,IAAI,CAAC,OAAO,OAAO;EACnB,OAAO,OAAO,OAAO,MAAM,IAAI,OAAO,IAAI,EAAE,QAAQ;CACtD,GACA,CAAC,OAAO,MAAM,MAAM,CACtB;CAEA,MAAM,iBAAA,GAAA,MAAA,cAEF,UAGG;EACH,IAAI,CAAC,iBAAiB,KAAK,cAAc,KAAK,WAAW;EAEzD,MAAM,SAAA,GAAA,YAAA,YAAmB,KAAK;EAC9B,IAAI,CAAC,OAAO;EAEZ,MAAM,KAAK,OAAO,OAAO,MAAM,IAAI,OAAO,IAAI;EAI9C,IAAI,aAA0B;EAC9B,IAAI,eAAe;EACnB,KAAK,MAAM,KAAK,QAAQ;GACtB,MAAM,IAAI,aAAa,EAAE,MAAM,EAAE;GACjC,IAAI,CAAC,GAAG;GACR,MAAM,WAAW,KAAK,IAAI,EAAE,KAAK,QAAQ,IAAI,GAAG,QAAQ,CAAC;GACzD,IAAI,WAAW,cAAc;IAC3B,eAAe;IACf,aAAa,EAAE;GACjB;EACF;EAEA,IAAI,CAAC,YAAY;EAEjB,YAAY;GACV,aAAa,EAAE,MAAM,WAAW;GAChC,aAAa,OAAO,UAAU,IAAI,OAAO;GACzC,YAAY,OAAO;EACrB,CAAC;CACH,GACA;EACE;EACA;EACA;EACA;EACA;EACA,KAAK;EACL,KAAK;CACP,CACF;CAEA,MAAM,cAAiC,cACnC,OAAO,SAAS,GAAG,MAAM;EACvB,MAAM,IAAI,aAAa,EAAE,MAAM,YAAY,IAAI;EAC/C,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,MAAM,YAAY,IAAI,GAAG,OAAO,CAAC;EAC3D,OAAO,CACL;GACE,KAAK,EAAE;GACP,OAAO,EAAE,SAAS,EAAE;GACpB,OACE,EAAE,SAAU,cAAc,IAAI,cAAc;GAC9C,OAAO,YAAY,EAAE,KAAK;GAC1B,QAAQ,EAAE,SAAU,gBAA2B;EACjD,CACF;CACF,CAAC,IACD,CAAC;CAEL,MAAM,CAAC,YAAY,eAAeC,yBAAAA,gBAAgC;CAClE,MAAM,aAAaC,yBAAAA,qBAAqB;EACtC,SAAS,eAAe;EACxB,SAAS,cAAc,OAAO;EAC9B;EACA;EACA,UAAU,YAAY;EACtB,WAAW,YAAY;EACvB,WAAW;CACb,CAAC;CAED,IAAI,QAAQ,MAAM,SAAS,IAAI,OAAO;CAEtC,OACE,iBAAA,GAAA,kBAAA,MAAC,OAAD;EAAK,YAAA,GAAA,GAAA,IAAc,YAAY,SAAS;YAAxC;GACE,iBAAA,GAAA,kBAAA,MAAC,OAAD;IAAK,WAAU;IAAgB;IAAe;cAA9C,CACE,iBAAA,GAAA,kBAAA,KAAC,QAAD,EAAA,UACE,iBAAA,GAAA,kBAAA,KAAC,YAAD;KAAU,IAAI;eACZ,iBAAA,GAAA,kBAAA,KAAC,QAAD;MAAM,QAAQ;MAAa,OAAO;MAAY,GAAG;MAAG,GAAG;KAAI,CAAA;IACnD,CAAA,EACN,CAAA,GACN,iBAAA,GAAA,kBAAA,MAACC,YAAAA,OAAD;KAAO,MAAM,OAAO;KAAM,KAAK,OAAO;eAAtC;MAEG,YACC,OAAO,KAAK,SACV,iBAAA,GAAA,kBAAA,KAAC,QAAD;OACE,WAAU;OAEV,iBAAgB;OAChB,IAAI;OACJ,IAAI;OACJ,IAAI,OAAO,IAAI;OACf,IAAI,OAAO,IAAI;MAChB,GANM,UAAU,MAMhB,CACF;MAGH,iBAAA,GAAA,kBAAA,KAAC,QAAD;OACE,WAAU;OACV,IAAI;OACJ,IAAI;OACJ,IAAI;OACJ,IAAI;MACL,CAAA;MAGA,gBAAgB,KAAK,QAAQ;OAC5B,MAAM,IAAI,OAAO,IAAI,IAAI;OACzB,IAAI,CAAC,OAAO,SAAS,CAAC,KAAK,IAAI,KAAK,IAAI,YAAY,OAAO;OAG3D,MAAM,YAAY,IAAI,aAAa;OACnC,OACE,iBAAA,GAAA,kBAAA,MAAC,KAAD;QAAiB,eAAc;kBAA/B,CACE,iBAAA,GAAA,kBAAA,KAAC,QAAD;SACE,WAAU;SACV,iBAAgB;SAChB,IAAI;SACJ,IAAI;SACJ,IAAI;SACJ,IAAI;QACL,CAAA,GACA,IAAI,SAAS,QACZ,iBAAA,GAAA,kBAAA,KAAC,QAAD;SACE,WAAU;SACV,IAAG;SACH,YAAY,YAAY,QAAQ;SAChC,GAAG,KAAK,YAAY,KAAK;SACzB,GAAG;mBAEF,IAAI;QACD,CAAA,CAEP;UApBK,IAAI,GAoBT;MAEP,CAAC;MAGA,OAAO,KAAK,MAAM,UACjB,iBAAA,GAAA,kBAAA,KAAC,QAAD;OACE,IAAG;OACH,MAAK;OACL,UAAU;OAEV,YACE,UAAU,IACN,UACA,UAAU,OAAO,SAAS,IACxB,QACA;OAER,GAAG,OAAO,IAAI;OACd,GAAG,cAAc;iBAEhB,eAAe,IAAI;MAChB,GAZC,KAAK,KAAK,QAAQ,GAYnB,CACP;MAMA,cAAc,KAAA,KACb,iBAAA,GAAA,kBAAA,KAAC,QAAD;OACE,QAAO;OACP,aAAa;OACb,IAAI;OACJ,IAAI;OACJ,IAAI;OACJ,IAAI;MACL,CAAA;MAEF,OAAO,KAAK,SAAS;OACpB,MAAM,IAAI,OAAO,IAAI;OACrB,OACE,iBAAA,GAAA,kBAAA,MAAC,KAAD,EAAA,UAAA,CACG,cAAc,KAAA,KACb,iBAAA,GAAA,kBAAA,KAAC,QAAD;QACE,QAAO;QACP,aAAa;QACb,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI;OACL,CAAA,GAEH,iBAAA,GAAA,kBAAA,KAAC,QAAD;QACE,IAAG;QACH,MAAK;QACL,UAAU;QACV,YAAW;QACX,GAAG,cAAc,KAAA,IAAY,KAAK;QAC/B;kBAEF,cAAc,KAAA,IACX,YAAY,IAAI,IAChB,YAAY,IAAI;OAChB,CAAA,CACL,EAAA,GAvBK,KAAK,MAuBV;MAEP,CAAC;MACA,cAAc,KAAA,KACb,iBAAA,GAAA,kBAAA,KAAC,QAAD;OACE,MAAK;OACL,UAAU;OACV,YAAY;OACZ,YAAW;OACX,GAAG,CAAC,OAAO;OACX,GAAG;iBAEF;MACG,CAAA;MAGR,iBAAA,GAAA,kBAAA,KAAC,KAAD;OAAG,UAAU,QAAQ,WAAW;OAAI,eAAY;iBAC7C,OAAO,KAAK,GAAG,MACd,iBAAA,GAAA,kBAAA,KAACC,YAAAA,UAAD;QACE,YAAA,GAAA,GAAA,IAAc,YAAY,IAAI,YAAY,SAAS,EAAE,SAAS;QAC9D,OAAO,aAAa,EAAE,SAAS,YAAY;QAC3C,MAAM,EAAE;QACR,MAAK;QAEL,iBACE,EAAE,SAAU,EAAE,eAAe,QAAS,KAAA;QAExC,aAAa;QACb,IAAI,MAAM,OAAO,EAAE,IAAI;QACvB,IAAI,MAAM,OAAO,EAAE,KAAK;OACzB,GAPM,EAAE,EAOR,CACF;MACA,CAAA;MAEF,KAAK,aACJ,iBAAA,GAAA,kBAAA,KAAC,QAAD;OACE,eAAY;OACZ,MAAK;OACL,QAAQ;OACR,eAAc;OACd,OAAO,KAAK,IACV,OAAO,IAAI,KAAK,KAAK,UAAU,EAAE,CAAC,IAChC,OAAO,IAAI,KAAK,KAAK,UAAU,EAAE,CAAC,CACtC;OACA,GAAG,KAAK,IACN,OAAO,IAAI,KAAK,KAAK,UAAU,EAAE,CAAC,GAClC,OAAO,IAAI,KAAK,KAAK,UAAU,EAAE,CAAC,CACpC;OACA,GAAG;MACJ,CAAA;OAGD,iBAAiB,aACjB,iBAAA,GAAA,kBAAA,KAAC,QAAD;OACE,MAAK;OACL,QAAQ;OACR,OAAO,WAAW,EAAE,aAAa,QAAQ,IAAI,KAAA;OAC7C,OAAO;OACP,GAAG;OACH,GAAG;OACH,oBAAoB;QAClB,IAAI,CAAC,KAAK,YAAY,YAAY;OACpC;OACA,cAAc,UAAU;QACtB,IAAI,KAAK,YAAY;SACnB,MAAM,UAAU,iBAAiB,KAAK;SACtC,IAAI,WAAW,MAAM,KAAK,cAAc,OAAO;SAC/C;QACF;QACA,cAAc,KAAK;OACrB;OACA,gBAAgB,UAAU;QACxB,IAAI,CAAC,YAAY,MAAM,gBAAgB,SAAS;QAChD,IAAI,MAAM,WAAW,GAAG;QACxB,MAAM,UAAU,iBAAiB,KAAK;QACtC,IAAI,WAAW,MAAM;QACrB,MAAM,cAAc,oBAAoB,MAAM,SAAS;QACvD,YAAY;QACZ,KAAK,cAAc,OAAO;OAC5B;OACA,gBAAgB,UAAU;QACxB,IAAI,CAAC,UAAU;QACf,MAAM,UAAU,iBAAiB,KAAK;QACtC,IAAI,WAAW,MAAM,KAAK,cAAc,OAAO;OACjD;OACA,cAAc,UAAU;QACtB,IAAI,CAAC,UAAU;QACf,MAAM,UAAU,iBAAiB,KAAK;QACtC,IAAI,WAAW,MAAM,KAAK,YAAY,OAAO;aACxC,KAAK,gBAAgB;OAC5B;OACA,uBAAuB;QACrB,KAAK,gBAAgB;OACvB;OACA,qBAAqB;QACnB,IAAI,UAAU,KAAK,cAAc;OACnC;OACA,eAAe,UAAU;QACvB,IAAI,CAAC,UAAU;QACf,IAAI,MAAM,QAAQ,WAAW,GAAG;SAC9B,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,QAAQ,IAAI,MAAM,QAAQ,EAAE;SAClD,IAAI,CAAC,KAAK,CAAC,GAAG;SACd,MAAM,SAAA,GAAA,YAAA,YACJ,MAAM,eACN,cAAc,GAAG,CAAC,CACpB;SACA,IAAI,CAAC,OAAO;SACZ,MAAM,WAAW,KAAK,IACpB,GACA,KAAK,IAAI,IAAI,MAAM,IAAI,OAAO,QAAQ,UAAU,CAClD;SACA,KAAK,aAAa,cAAc,GAAG,CAAC,GAAG,QAAQ;SAC/C,YAAY;SACZ;QACF;QACA,IAAI,MAAM,QAAQ,WAAW,KAAK,KAAK,UAAU;SAC/C,MAAM,SAAA,GAAA,YAAA,YAAmB,KAAK;SAC9B,IAAI,CAAC,OAAO;SACZ,KAAK,WAAW;UACd,IAAI,MAAM,IAAI,OAAO,QAAQ;UAC7B,IAAI,MAAM,IAAI,OAAO,OAAO;SAC9B,CAAC;SACD,YAAY;QACd;OACF;OACA,cAAc,UAAU;QACtB,IAAI,YAAY,MAAM,QAAQ,WAAW,GAAG;SAC1C,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,QAAQ,IAAI,MAAM,QAAQ,EAAE;SAClD,IAAI,CAAC,KAAK,CAAC,GAAG;SACd,MAAM,SAAA,GAAA,YAAA,YACJ,MAAM,eACN,cAAc,GAAG,CAAC,CACpB;SACA,IAAI,CAAC,OAAO;SACZ,MAAM,WAAW,KAAK,IACpB,GACA,KAAK,IAAI,IAAI,MAAM,IAAI,OAAO,QAAQ,UAAU,CAClD;SACA,KAAK,YAAY,cAAc,GAAG,CAAC,GAAG,QAAQ;SAC9C;QACF;QACA,IAAI,MAAM,QAAQ,WAAW,KAAK,KAAK,UAAU;SAC/C,MAAM,SAAA,GAAA,YAAA,YAAmB,KAAK;SAC9B,IAAI,CAAC,OAAO;SACZ,KAAK,UAAU;UACb,IAAI,MAAM,IAAI,OAAO,QAAQ;UAC7B,IAAI,MAAM,IAAI,OAAO,OAAO;SAC9B,CAAC;SACD;QACF;QACA,IAAI,MAAM,QAAQ,WAAW,GAAG,cAAc,KAAK;OACrD;OACA,aAAa,UAAU;QACrB,IAAI,YAAY,MAAM,QAAQ,SAAS,GAAG,KAAK,WAAW;QAC1D,IAAI,MAAM,QAAQ,WAAW,GAAG;SAC9B,IAAI,UAAU,KAAK,SAAS;SAC5B,IAAI,UAAU,KAAK,MAAM;SACzB,YAAY;QACd;OACF;OACA,qBAAqB;QACnB,KAAK,WAAW;QAChB,KAAK,SAAS;OAChB;MACD,CAAA;MAIF,eACC,eACA,CAAC,KAAK,cACN,CAAC,KAAK,aACJ,iBAAA,GAAA,kBAAA,MAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAC,QAAD;OACE,WAAU;OACV,eAAc;OACd,iBAAgB;OAChB,IAAI,OAAO,YAAY,IAAI;OAC3B,IAAI,OAAO,YAAY,IAAI;OAC3B,IAAI;OACJ,IAAI;MACL,CAAA,GACA,OAAO,KAAK,GAAG,MAAM;OACpB,MAAM,IAAI,aAAa,EAAE,MAAM,YAAY,IAAI;OAC/C,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,MAAM,YAAY,IAAI,GAAG,OAAO;OAC1D,OACE,iBAAA,GAAA,kBAAA,KAAC,UAAD;QAEE,WACE,EAAE,QACE,KAAA,KAAA,GAAA,GAAA,IACG,WAAW,IAAI,WAAW,OAAO;QAE1C,IAAI,OAAO,EAAE,IAAI;QACjB,IAAI,OAAO,EAAE,KAAK;QAClB,MAAM,EAAE;QACR,eAAc;QACd,GAAG;QACH,QAAO;QACP,aAAa;OACd,GAbM,EAAE,EAaR;MAEL,CAAC,CACD,EAAA,CAAA;KAED;MACJ;;GAEJ,cAAc,WAAW,SAAS,KACjC,iBAAA,GAAA,kBAAA,KAAC,OAAD;IACE,WAAU;IACV,OAAO;KACL,QAAQ,OAAO;KACf,MAAM,OAAO;KACb,KAAK;KACL,OAAO;IACT;cAEC,WAAW,KAAK,SAAS;KACxB,MAAM,IAAI,OAAO,KAAK,IAAI;KAC1B,IAAI,CAAC,OAAO,SAAS,CAAC,KAAK,IAAI,KAAK,IAAI,YAAY,OAAO;KAC3D,OACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;MAEE,WAAU;MACV,OAAO;OAAE,MAAM;OAAG,KAAK;MAAE;gBAExB,KAAK;KACH,GALE,KAAK,GAKP;IAET,CAAC;GACE,CAAA;GAGN,KAAK,YAAY,kBAChB,iBAAA,GAAA,kBAAA,KAACC,yBAAAA,sBAAD;IAAsB,OAAO;IAAgB,SAAS,KAAK;GAAY,CAAA;GAGzE,iBAAA,GAAA,kBAAA,KAAC,OAAD;IACE,KAAK;IACL,WAAU;IACV,OAAO;KACL,MAAM,WAAW;KACjB,KAAK,WAAW;KAChB,SACE,eAAe,eAAe,CAAC,KAAK,aAAa,CAAC,KAAK,aACnD,IACA;KACN,YAAY,gBACR,2BACA;IACN;cAEC,eACC,iBAAA,GAAA,kBAAA,KAACC,yBAAAA,kBAAD;KACE,QAAQ,qBAAqB,YAAY,YAAY,IAAI;KACzD,MAAM;IACP,CAAA;GAEA,CAAA;EACF;;AAET"}
@@ -1,11 +1,11 @@
1
1
  "use client";
2
- import { localeNumberFormat } from "../utils/format.js";
2
+ import { useAnimatedChartDomain, useChartZoom } from "../hooks/use-chart-zoom.js";
3
+ import { useReducedMotion } from "../hooks/use-reduced-motion.js";
4
+ import { cn } from "../utils/cn.js";
5
+ import { getDocumentLang, localeNumberFormat } from "../utils/format.js";
3
6
  import { buildYAxisScale, formatYAxisTick } from "../utils/chart-scale.js";
4
7
  import { buildTimeTicks } from "../utils/chart-time-ticks.js";
5
- import { cn } from "../utils/cn.js";
6
- import { useReducedMotion } from "../hooks/use-reduced-motion.js";
7
8
  import { ChartTooltipCard, ChartZoomResetButton, clampTooltipPosition, useMeasuredSize } from "./chart.js";
8
- import { useAnimatedChartDomain, useChartZoom } from "../hooks/use-chart-zoom.js";
9
9
  import * as React$1 from "react";
10
10
  import { useCallback, useMemo } from "react";
11
11
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -67,7 +67,7 @@ function nearestDatum(data, date) {
67
67
  if (!d1) return d0;
68
68
  return date.valueOf() - d0.date.valueOf() > d1.date.valueOf() - date.valueOf() ? d1 : d0;
69
69
  }
70
- const defaultFormatDate = (date) => date.toLocaleDateString(void 0, {
70
+ const defaultFormatDate = (date) => date.toLocaleDateString(getDocumentLang(), {
71
71
  month: "short",
72
72
  day: "numeric"
73
73
  });