@eifi1/ui-kit 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (233) hide show
  1. package/README.md +32 -17
  2. package/dist/chart.d.ts +3 -2
  3. package/dist/components/alert-banner.d.ts +59 -10
  4. package/dist/components/alert-banner.js +114 -8
  5. package/dist/components/alert-banner.js.map +1 -1
  6. package/dist/components/amount-input.d.ts +5 -0
  7. package/dist/components/button-group.d.ts +26 -0
  8. package/dist/components/button-group.js +49 -0
  9. package/dist/components/button-group.js.map +1 -0
  10. package/dist/components/calculator.d.ts +5 -0
  11. package/dist/components/chart-zoom.d.ts +63 -14
  12. package/dist/components/chart-zoom.js +82 -16
  13. package/dist/components/chart-zoom.js.map +1 -1
  14. package/dist/components/chip.d.ts +67 -2
  15. package/dist/components/chip.js +73 -8
  16. package/dist/components/chip.js.map +1 -1
  17. package/dist/components/confirm-dialog.d.ts +120 -0
  18. package/dist/components/confirm-dialog.js +96 -0
  19. package/dist/components/confirm-dialog.js.map +1 -0
  20. package/dist/components/copy-button.d.ts +62 -0
  21. package/dist/components/copy-button.js +95 -0
  22. package/dist/components/copy-button.js.map +1 -0
  23. package/dist/components/data-table-filter-popover.d.ts +1 -1
  24. package/dist/components/data-table-filters.d.ts +1 -1
  25. package/dist/components/data-table-pagination.d.ts +5 -1
  26. package/dist/components/data-table-pagination.js +71 -58
  27. package/dist/components/data-table-pagination.js.map +1 -1
  28. package/dist/components/data-table-sort.d.ts +28 -5
  29. package/dist/components/data-table-sort.js +11 -7
  30. package/dist/components/data-table-sort.js.map +1 -1
  31. package/dist/components/data-table.d.ts +1 -1
  32. package/dist/components/data-table.js +544 -423
  33. package/dist/components/data-table.js.map +1 -1
  34. package/dist/components/date-picker.d.ts +51 -5
  35. package/dist/components/date-picker.js +152 -40
  36. package/dist/components/date-picker.js.map +1 -1
  37. package/dist/components/description-list.d.ts +60 -0
  38. package/dist/components/description-list.js +112 -0
  39. package/dist/components/description-list.js.map +1 -0
  40. package/dist/components/disclosure.d.ts +37 -2
  41. package/dist/components/disclosure.js +14 -5
  42. package/dist/components/disclosure.js.map +1 -1
  43. package/dist/components/facing-pair.d.ts +2 -0
  44. package/dist/components/file-button.d.ts +19 -1
  45. package/dist/components/file-button.js +8 -1
  46. package/dist/components/file-button.js.map +1 -1
  47. package/dist/components/file-dropzone.d.ts +56 -9
  48. package/dist/components/file-dropzone.js +100 -70
  49. package/dist/components/file-dropzone.js.map +1 -1
  50. package/dist/components/floating-panel.d.ts +107 -0
  51. package/dist/components/floating-panel.js +206 -0
  52. package/dist/components/floating-panel.js.map +1 -0
  53. package/dist/components/full-bleed-dialog.d.ts +12 -1
  54. package/dist/components/full-bleed-dialog.js +26 -5
  55. package/dist/components/full-bleed-dialog.js.map +1 -1
  56. package/dist/components/modal.d.ts +6 -2
  57. package/dist/components/modal.js +2 -1
  58. package/dist/components/modal.js.map +1 -1
  59. package/dist/components/number-field.d.ts +5 -0
  60. package/dist/components/number-input.d.ts +5 -0
  61. package/dist/components/numpad-sheet.d.ts +5 -0
  62. package/dist/components/progress-bar.d.ts +54 -0
  63. package/dist/components/progress-bar.js +94 -0
  64. package/dist/components/progress-bar.js.map +1 -0
  65. package/dist/components/scroll-area.d.ts +53 -0
  66. package/dist/components/scroll-area.js +86 -0
  67. package/dist/components/scroll-area.js.map +1 -0
  68. package/dist/components/separator.d.ts +23 -0
  69. package/dist/components/separator.js +24 -0
  70. package/dist/components/separator.js.map +1 -0
  71. package/dist/components/series-chart-ticks.d.ts +34 -1
  72. package/dist/components/series-chart-ticks.js +83 -1
  73. package/dist/components/series-chart-ticks.js.map +1 -1
  74. package/dist/components/series-chart.d.ts +314 -19
  75. package/dist/components/series-chart.js +510 -120
  76. package/dist/components/series-chart.js.map +1 -1
  77. package/dist/components/settings-fields.d.ts +2 -0
  78. package/dist/components/skeleton.d.ts +36 -0
  79. package/dist/components/skeleton.js +35 -0
  80. package/dist/components/skeleton.js.map +1 -0
  81. package/dist/components/stat-tile.d.ts +60 -6
  82. package/dist/components/stat-tile.js +60 -26
  83. package/dist/components/stat-tile.js.map +1 -1
  84. package/dist/components/table.d.ts +83 -0
  85. package/dist/components/table.js +166 -0
  86. package/dist/components/table.js.map +1 -0
  87. package/dist/components/time-input.d.ts +2 -0
  88. package/dist/components/toggle-legend.d.ts +3 -2
  89. package/dist/components/toggle-legend.js +1 -1
  90. package/dist/components/toggle-legend.js.map +1 -1
  91. package/dist/components/tooltip.d.ts +10 -4
  92. package/dist/components/tooltip.js +23 -6
  93. package/dist/components/tooltip.js.map +1 -1
  94. package/dist/components/tree-view.d.ts +129 -0
  95. package/dist/components/tree-view.js +376 -0
  96. package/dist/components/tree-view.js.map +1 -0
  97. package/dist/components/treemap.d.ts +9 -2
  98. package/dist/components/treemap.js +2 -1
  99. package/dist/components/treemap.js.map +1 -1
  100. package/dist/components/ui.d.ts +92 -14
  101. package/dist/components/ui.js +112 -30
  102. package/dist/components/ui.js.map +1 -1
  103. package/dist/components/use-table-state.d.ts +1 -1
  104. package/dist/{data-table-filters-noy0Abvi.d.ts → data-table-filters-CF1PXqjQ.d.ts} +73 -3
  105. package/dist/data-table.d.ts +2 -2
  106. package/dist/data-table.js.map +1 -1
  107. package/dist/hooks/use-copy-to-clipboard.d.ts +28 -0
  108. package/dist/hooks/use-copy-to-clipboard.js +81 -0
  109. package/dist/hooks/use-copy-to-clipboard.js.map +1 -0
  110. package/dist/hooks/use-debounce.d.ts +43 -0
  111. package/dist/hooks/use-debounce.js +56 -0
  112. package/dist/hooks/use-debounce.js.map +1 -0
  113. package/dist/hooks/use-file-drop.d.ts +72 -0
  114. package/dist/hooks/use-file-drop.js +57 -0
  115. package/dist/hooks/use-file-drop.js.map +1 -0
  116. package/dist/i18n/defaults.d.ts +5 -0
  117. package/dist/i18n/defaults.js +7 -1
  118. package/dist/i18n/defaults.js.map +1 -1
  119. package/dist/i18n/kit-labels.d.ts +17 -0
  120. package/dist/i18n/kit-labels.js +6 -2
  121. package/dist/i18n/kit-labels.js.map +1 -1
  122. package/dist/i18n/locales/de-CH-informal.d.ts +43 -0
  123. package/dist/i18n/locales/de-CH-informal.js +8 -0
  124. package/dist/i18n/locales/de-CH-informal.js.map +1 -0
  125. package/dist/i18n/locales/de-CH.d.ts +5 -0
  126. package/dist/i18n/locales/de-CH.js +1 -14
  127. package/dist/i18n/locales/de-CH.js.map +1 -1
  128. package/dist/i18n/locales/de-informal.d.ts +64 -0
  129. package/dist/i18n/locales/de-informal.js +37 -0
  130. package/dist/i18n/locales/de-informal.js.map +1 -0
  131. package/dist/i18n/locales/de.d.ts +5 -0
  132. package/dist/i18n/locales/de.js +25 -0
  133. package/dist/i18n/locales/de.js.map +1 -1
  134. package/dist/i18n/locales/es.d.ts +5 -0
  135. package/dist/i18n/locales/es.js +25 -0
  136. package/dist/i18n/locales/es.js.map +1 -1
  137. package/dist/i18n/locales/fr.d.ts +5 -0
  138. package/dist/i18n/locales/fr.js +25 -0
  139. package/dist/i18n/locales/fr.js.map +1 -1
  140. package/dist/i18n/locales/hu.d.ts +5 -0
  141. package/dist/i18n/locales/hu.js +25 -0
  142. package/dist/i18n/locales/hu.js.map +1 -1
  143. package/dist/i18n/locales/it.d.ts +5 -0
  144. package/dist/i18n/locales/it.js +25 -0
  145. package/dist/i18n/locales/it.js.map +1 -1
  146. package/dist/i18n/locales/zh.d.ts +5 -0
  147. package/dist/i18n/locales/zh.js +25 -0
  148. package/dist/i18n/locales/zh.js.map +1 -1
  149. package/dist/i18n/swiss.d.ts +13 -0
  150. package/dist/i18n/swiss.js +19 -0
  151. package/dist/i18n/swiss.js.map +1 -0
  152. package/dist/index.d.ts +26 -11
  153. package/dist/index.js +22 -0
  154. package/dist/index.js.map +1 -1
  155. package/dist/lib/dates.d.ts +37 -1
  156. package/dist/lib/dates.js +19 -0
  157. package/dist/lib/dates.js.map +1 -1
  158. package/dist/rhf/form.d.ts +2 -0
  159. package/dist/rhf.d.ts +2 -0
  160. package/dist/search/command-palette.d.ts +15 -1
  161. package/dist/search/command-palette.js +10 -2
  162. package/dist/search/command-palette.js.map +1 -1
  163. package/dist/shell/app-shell.js +2 -2
  164. package/dist/shell/app-shell.js.map +1 -1
  165. package/dist/wizard/stepper-nav.d.ts +35 -2
  166. package/dist/wizard/stepper-nav.js +54 -22
  167. package/dist/wizard/stepper-nav.js.map +1 -1
  168. package/dist/wizard/types.d.ts +107 -5
  169. package/dist/wizard/types.js +2 -1
  170. package/dist/wizard/types.js.map +1 -1
  171. package/dist/wizard/use-wizard.js +141 -21
  172. package/dist/wizard/use-wizard.js.map +1 -1
  173. package/dist/wizard/wizard-summary.d.ts +10 -2
  174. package/dist/wizard/wizard-summary.js +3 -1
  175. package/dist/wizard/wizard-summary.js.map +1 -1
  176. package/dist/wizard.d.ts +4 -1
  177. package/dist/wizard.js.map +1 -1
  178. package/package.json +1 -1
  179. package/src/components/alert-banner.tsx +211 -20
  180. package/src/components/button-group.tsx +75 -0
  181. package/src/components/chart-zoom.tsx +158 -20
  182. package/src/components/chip.tsx +160 -9
  183. package/src/components/confirm-dialog.tsx +242 -0
  184. package/src/components/copy-button.tsx +158 -0
  185. package/src/components/data-table-pagination.tsx +19 -6
  186. package/src/components/data-table-sort.ts +49 -10
  187. package/src/components/data-table.tsx +293 -24
  188. package/src/components/date-picker.tsx +262 -57
  189. package/src/components/description-list.tsx +174 -0
  190. package/src/components/disclosure.tsx +58 -5
  191. package/src/components/file-button.tsx +22 -2
  192. package/src/components/file-dropzone.tsx +198 -100
  193. package/src/components/floating-panel.tsx +341 -0
  194. package/src/components/full-bleed-dialog.tsx +48 -5
  195. package/src/components/modal.tsx +9 -2
  196. package/src/components/progress-bar.tsx +163 -0
  197. package/src/components/scroll-area.tsx +129 -0
  198. package/src/components/separator.tsx +37 -0
  199. package/src/components/series-chart-ticks.ts +135 -0
  200. package/src/components/series-chart.tsx +934 -67
  201. package/src/components/skeleton.tsx +65 -0
  202. package/src/components/stat-tile.tsx +160 -27
  203. package/src/components/table.tsx +263 -0
  204. package/src/components/toggle-legend.tsx +4 -3
  205. package/src/components/tooltip.tsx +40 -12
  206. package/src/components/tree-view.tsx +589 -0
  207. package/src/components/treemap.tsx +10 -2
  208. package/src/components/ui.tsx +268 -42
  209. package/src/data-table.ts +2 -0
  210. package/src/hooks/use-copy-to-clipboard.ts +122 -0
  211. package/src/hooks/use-debounce.ts +105 -0
  212. package/src/hooks/use-file-drop.ts +123 -0
  213. package/src/i18n/defaults.ts +6 -0
  214. package/src/i18n/kit-labels.tsx +19 -0
  215. package/src/i18n/locales/de-CH-informal.ts +10 -0
  216. package/src/i18n/locales/de-CH.ts +1 -16
  217. package/src/i18n/locales/de-informal.ts +61 -0
  218. package/src/i18n/locales/de.ts +25 -0
  219. package/src/i18n/locales/es.ts +25 -0
  220. package/src/i18n/locales/fr.ts +25 -0
  221. package/src/i18n/locales/hu.ts +25 -0
  222. package/src/i18n/locales/it.ts +25 -0
  223. package/src/i18n/locales/zh.ts +25 -0
  224. package/src/i18n/swiss.ts +25 -0
  225. package/src/index.ts +29 -0
  226. package/src/lib/dates.ts +48 -0
  227. package/src/search/command-palette.tsx +29 -3
  228. package/src/shell/app-shell.tsx +2 -2
  229. package/src/wizard/stepper-nav.tsx +102 -28
  230. package/src/wizard/types.ts +106 -4
  231. package/src/wizard/use-wizard.ts +211 -31
  232. package/src/wizard/wizard-summary.tsx +24 -12
  233. package/src/wizard.ts +3 -2
@@ -1,7 +1,9 @@
1
1
  import * as react from 'react';
2
- import { ReactNode } from 'react';
3
- import { ZoomBinding } from './chart-zoom.js';
2
+ import { ReactNode, RefObject } from 'react';
3
+ import { ZoomAxesSetting, ZoomBinding } from './chart-zoom.js';
4
+ import { LegendEntry } from './toggle-legend.js';
4
5
  import { SeriesChartLabels } from './series-chart-labels.js';
6
+ import { TimeTickUnit } from './series-chart-ticks.js';
5
7
  import 'recharts';
6
8
 
7
9
  interface SeriesChartSeries {
@@ -16,15 +18,93 @@ interface SeriesChartSeries {
16
18
  * reference against the measurement. Shorthand for `dash: 1`. */
17
19
  dashed?: boolean;
18
20
  /** Which of {@link STROKE_PATTERNS} this line takes, for charts where the stroke says
19
- * WHICH QUANTITY and the colour says WHICH MEASUREMENT. */
20
- dash?: number;
21
+ * WHICH QUANTITY and the colour says WHICH MEASUREMENT.
22
+ *
23
+ * Or an SVG `stroke-dasharray` string of the caller's own, for a pattern the five do
24
+ * not have: keksdose's `"4 3"`, a tighter dash than the ladder's `"5 4"` that its
25
+ * hand-drawn recharts lines used before the kit. The legend
26
+ * entry ({@link seriesLegendEntries}) carries the same string, so it draws the same
27
+ * pattern. */
28
+ dash?: number | string;
21
29
  /** `stepAfter`, for a whole-number channel that jumps rather than travels — a
22
30
  * straight line between index 0 and index 1 draws an index of 0.5, which does not
23
31
  * exist. Drawn in the {@link STEP_DASH} pattern, whatever `dash` says. */
24
32
  step?: boolean;
25
33
  /** Which of `axes` this line is measured on. Default: `"y"`, the single one. */
26
34
  axis?: string;
35
+ /**
36
+ * The mark. `"line"` (the default) is what every chart before 0.8.0 drew. `"bar"` and
37
+ * `"area"` are read as a LENGTH from zero, so the axis they stand on always includes
38
+ * zero (see `SeriesChartAxis.includeZero`) and the zoom treats them differently (see
39
+ * `defaultZoomAxes`). Bars without a `stack` stand side by side in each slot — the
40
+ * grouped bars of keksdose's payee report.
41
+ */
42
+ type?: SeriesChartType;
43
+ /**
44
+ * Bars or areas with the same `stack` are drawn on top of each other and the axis is
45
+ * fitted to their SUM (positive and negative layers apart, like recharts'
46
+ * `stackOffset="sign"`). keksdose's spending-by-category area. Ignored on a line:
47
+ * recharts cannot stack one.
48
+ */
49
+ stack?: string;
50
+ /**
51
+ * Marks on the line's (or area's) points. `true` rings every sample — the price
52
+ * history, where a shop has a value only on the days somebody shopped there and the
53
+ * dots are the only thing saying which points were MEASURED. A function decides per
54
+ * point: `true` for the default dot, `false`/`null` for none, or any SVG node drawn
55
+ * as-is at `point.cx`/`point.cy` — a buy/sell marker on keksdose's paper price.
56
+ * Never called for a point with no value. Bars have no points, and ignore it.
57
+ */
58
+ dot?: boolean | ((point: SeriesChartPoint) => ReactNode);
59
+ /** Line (or area outline) weight in px. Default 2, or 1.5 for a `step`. keksdose
60
+ * draws the subject of a chart at 2.5 and the reference it is read against at 1.5. */
61
+ strokeWidth?: number;
62
+ /** `"linear"` for a line that must not look smoothed — keksdose's cash-buffer
63
+ * PROJECTION, a straight extrapolation that a monotone curve would dress up as data.
64
+ * Default `"monotone"`; `step` wins over both. */
65
+ curve?: "monotone" | "linear";
66
+ /** An area's or bar's fill opacity. Default: 1 for a bar, 0.55 for a stacked area
67
+ * (the layers must stay tellable apart where they meet) and 0.2 for a single one. */
68
+ fillOpacity?: number;
69
+ /**
70
+ * The dot that follows the pointer along a line or an area. `false` takes it off a
71
+ * series that is not a measurement — keksdose's cash-buffer PROJECTION, where a hover
72
+ * ring on the extrapolated line reads as a sampled value (`cash-buffer-chart.tsx`).
73
+ * `{ r }` sets its radius. Default: recharts' dot. Bars have none, and ignore it.
74
+ */
75
+ activeDot?: boolean | {
76
+ r?: number;
77
+ };
78
+ }
79
+ /** What a series draws. See {@link SeriesChartSeries.type}. */
80
+ type SeriesChartType = "line" | "bar" | "area";
81
+ /** One point of a series, as a `dot` function is handed it. */
82
+ interface SeriesChartPoint {
83
+ /** The series' key. */
84
+ key: string;
85
+ /** The row's position in `rows`. */
86
+ index: number;
87
+ /** The caller's own row, with everything the chart did not plot still in it. */
88
+ row: SeriesChartRow;
89
+ /** The abscissa in the caller's terms: the number, the category, or (time) a Date. */
90
+ x: SeriesChartXValue;
91
+ value: number;
92
+ /** Where the point is drawn, in the chart's pixels. */
93
+ cx: number;
94
+ cy: number;
95
+ /** The series' paint, `var(--color-<key>)`. */
96
+ color: string;
27
97
  }
98
+ /** A row of a series chart: one abscissa value and the series' values at it. Anything
99
+ * else in it (a raw ISO period for a drilldown) rides along untouched and is handed
100
+ * back in {@link SeriesChartPoint.row} and {@link SeriesChartHit.row}. */
101
+ type SeriesChartRow = Readonly<Record<string, unknown>>;
102
+ /** An abscissa value: a number (`x.type: "number"`), a category (a string, a number or
103
+ * a Date standing for a period), or a time (a Date, epoch ms or an ISO string). */
104
+ type SeriesChartXValue = number | string | Date;
105
+ /** Ticks a caller decides — a list, or a function of the domain on show, so a zoom
106
+ * window gets ticks from the same rule instead of none. */
107
+ type SeriesChartTickValues<T> = readonly T[] | ((domain: [number, number]) => readonly T[] | undefined);
28
108
  interface SeriesChartAxisShape {
29
109
  id: string;
30
110
  /**
@@ -49,6 +129,21 @@ interface SeriesChartAxisShape {
49
129
  * tooltip gets it from `valueFormat`. Default: `Intl.NumberFormat` in the kit's
50
130
  * locale, up to two fraction digits. */
51
131
  format?: (value: number) => string;
132
+ /**
133
+ * The tick values, instead of the round ones the chart picks. For a grid the DATA
134
+ * dictates — keksdose's price axes tick on whole cents (`pricePaddedDomain`), where a
135
+ * 1/2/5 ladder would print €1.25 under a formatter that can only say €1.3. Values
136
+ * outside the domain on show are dropped; a function is asked again for every zoom
137
+ * window, so the cent grid can refine with it.
138
+ */
139
+ tickValues?: SeriesChartTickValues<number>;
140
+ /**
141
+ * Keep zero inside the fitted band. On by default for an axis carrying a bar or an
142
+ * area — their length IS the value, and a truncated baseline draws 40 as three times
143
+ * 20 — and off for lines, whose shape is the point (a stock price anchored at zero is
144
+ * a hairline). A pinned `domain` is left alone either way.
145
+ */
146
+ includeZero?: boolean;
52
147
  }
53
148
  /**
54
149
  * A y axis — and a VISIBLE one says what it measures.
@@ -66,21 +161,111 @@ type SeriesChartAxis = SeriesChartAxisShape & ({
66
161
  title?: string;
67
162
  hide: true;
68
163
  });
164
+ /**
165
+ * What a tick or the tooltip heading of the abscissa is handed besides its position —
166
+ * the value in the caller's own terms, which on a category or time axis is not the
167
+ * number the plot runs on.
168
+ */
169
+ interface SeriesChartXTick {
170
+ /** The number itself, the row's category, or (time) a Date. */
171
+ value: SeriesChartXValue;
172
+ /** The slot, on a category axis: the row's index in `rows`. */
173
+ index?: number;
174
+ /** On a time axis: what one step of the ticks on show is, so a label can say as much
175
+ * as it means — a month start as "Mar 26", a midnight as "14 Mar". */
176
+ unit?: TimeTickUnit;
177
+ }
69
178
  interface SeriesChartX {
179
+ /**
180
+ * What the abscissa is.
181
+ *
182
+ * - `"number"` (the default) — a number line, and all a chart before 0.8.0 could draw.
183
+ * - `"category"` — PERIODS or names, one evenly spaced slot per row, in row order:
184
+ * keksdose's months, quarters and budget categories, which it used to hand recharts
185
+ * preformatted. The values stay the caller's own — `"2026-05"`, a Date for the
186
+ * month, a category name — and need not be sortable, unique or numeric. The plot
187
+ * runs on the slot INDEX, which is what lets it zoom: a drag across the third to the
188
+ * ninth month shows those months, a tick on each whole slot and the bars clipped at
189
+ * the edge. What else zooms depends on the MARKS, not the axis — see `zoomAxes`.
190
+ * - `"time"` — real TIME: a Date, epoch ms or an ISO string per row, placed by when
191
+ * it happened. keksdose's price history and cash buffer, where a slot per row would
192
+ * draw two receipts a day apart and two five months apart the same width. Ticks fall
193
+ * on calendar boundaries (midnights, Mondays, month and quarter starts, new years)
194
+ * in local time; a date-only ISO string is LOCAL midnight, not the UTC one
195
+ * `new Date("2026-05-01")` gives, which lands on the previous day west of Greenwich.
196
+ * Zooms like a number line.
197
+ */
198
+ type?: "number" | "category" | "time";
70
199
  /** Row key of the abscissa. Default `"x"`, which is what {@link mergeSeries} writes. */
71
200
  key?: string;
72
201
  /** What the abscissa is, with its unit. Drawn under the axis. */
73
202
  title?: string;
74
- /** A tick, formatted — bare, like the y axes'. */
75
- format?: (value: number) => string;
203
+ /**
204
+ * A tick, formatted — bare, like the y axes'.
205
+ *
206
+ * `value` is the POSITION on the number line the plot runs on — the number itself,
207
+ * epoch ms, or the slot index — so the one-argument formatters every chart before
208
+ * 0.8.0 passes keep their meaning, and a time axis' `(ms) => …` is the tickFormatter
209
+ * keksdose already has. The caller's own value (the category, the Date) is `tick.value`.
210
+ * Default: the kit's number format; a category as is (a number formatted, a Date as a
211
+ * medium date); a time as much of the date as the tick step means.
212
+ */
213
+ format?: (value: number, tick: SeriesChartXTick) => string;
76
214
  /**
77
215
  * Whether this chart prints the abscissa's ticks. On by default; off for every chart
78
216
  * of a stack sharing one x window but the bottom one, which prints them for all. It
79
217
  * costs no alignment: the x mapping is decided by the margins and the y bands.
80
218
  */
81
219
  ticks?: boolean;
82
- /** The tooltip's heading. Default: the abscissa value through `format`. */
83
- label?: (value: number) => ReactNode;
220
+ /** The tooltip's heading. Default: `format` — or, on a time axis, a medium date (with
221
+ * the time for hourly data), since a tick's "Mar 26" is not which day it was. */
222
+ label?: (value: number, tick: SeriesChartXTick) => ReactNode;
223
+ /** The ticks instead of the automatic ones, in the caller's terms: numbers, the
224
+ * categories to label, or instants. See `SeriesChartAxis.tickValues`. */
225
+ tickValues?: SeriesChartTickValues<SeriesChartXValue>;
226
+ /**
227
+ * Tilt the tick labels by this many degrees — negative rises to the right. For long
228
+ * category names that do not fit side by side: keksdose's budget performance draws its
229
+ * categories at −45° (`budget-performance-tab.tsx`). The label is anchored by its END
230
+ * for a negative angle and its START for a positive one, so it hangs off the tick
231
+ * instead of being centred across it; the anchor is physical, like the plot (see
232
+ * `ChartContainer`), so it is the same in RTL. The band under the axis grows to the
233
+ * rotated height of the longest label on show, estimated from its length (at most
234
+ * 120 px, past which a label is clipped). Default 0.
235
+ */
236
+ tickAngle?: number;
237
+ /**
238
+ * On a `"number"` axis, tick only on whole numbers: a step of 1 at the least, so a
239
+ * five-point index series reads 0 1 2 3 4 rather than 0 0.5 1 … 4 — ticks at
240
+ * positions no row can have (keksdose's short step series). A zoom window that holds
241
+ * no whole number falls back to the ordinary ticks rather than to none.
242
+ *
243
+ * AUTOMATIC by default — on when every row's x is a whole number — because that is
244
+ * exactly the case the half ticks are wrong in, and it changes nothing elsewhere: a
245
+ * span wider than about eight already ticks on whole steps. `false` for a continuous
246
+ * quantity that merely happens to be sampled on whole numbers (1 Hz steps) and whose
247
+ * zoom should still be ruled in fractions; `true` to force it over rows that are not.
248
+ * Ignored on category (already one tick per slot) and time axes.
249
+ */
250
+ integerTicks?: boolean;
251
+ }
252
+ /** Room for the tooltip beyond the chart — see {@link SeriesChartProps.tooltip}. */
253
+ interface SeriesChartTooltip {
254
+ /** Let the tooltip run past the chart's own box on that axis instead of recharts
255
+ * clamping it inside. Default: `{ x: true }` when `boundary` is set, else neither. */
256
+ allowEscapeViewBox?: {
257
+ x?: boolean;
258
+ y?: boolean;
259
+ };
260
+ /**
261
+ * The element that actually CLIPS the chart — usually a horizontal-scroll wrapper
262
+ * around a chart wider than the card. The tooltip then flips to the left of the cursor
263
+ * when it would spill past that element's visible right edge (see
264
+ * `ChartTooltipContent`'s `boundaryRef`), rather than against the wide chart's far edge
265
+ * the reader has not scrolled to. keksdose's budget performance, which keeps a scroll
266
+ * wrapper and a per-category `minWidth` (`budget-performance-tab.tsx`).
267
+ */
268
+ boundary?: RefObject<HTMLElement | null>;
84
269
  }
85
270
  /**
86
271
  * A vertical segment in data coordinates — two y at one x, which a row-per-abscissa
@@ -99,9 +284,74 @@ interface SeriesChartSpan {
99
284
  /** Default: `var(--text-muted)`. */
100
285
  color?: string;
101
286
  }
287
+ /** The colours a reference or a marker can take by name — the kit's semantic tokens,
288
+ * so a threshold reads the same on every chart and flips with the theme. */
289
+ type SeriesChartTone = "muted" | "brand" | "income" | "expense" | "net" | "success" | "warning" | "danger" | "info";
290
+ /**
291
+ * A line across the whole plot at one value: a threshold, a target, an event.
292
+ *
293
+ * keksdose's cash buffer draws "one month of runway" across at y = 30 and the projected
294
+ * depletion date down at its x. Unlike a {@link SeriesChartSpan}, which closes a shape
295
+ * in data coordinates, a reference spans the plot, whatever the zoom.
296
+ *
297
+ * A reference is part of the FITTED band: one outside the data widens the axis to show
298
+ * it, because a threshold the reader cannot see is not a threshold. A pinned domain or a
299
+ * zoom window does not widen — there it is discarded when outside, like a span.
300
+ */
301
+ interface SeriesChartReference {
302
+ /** Distinct within the chart. Default: its position in the list. */
303
+ key?: string;
304
+ /** `"x"` for a vertical line at an abscissa, otherwise the id of the y axis the value
305
+ * is measured on. Default `"y"`, the single one — so no y axis may be called `"x"`. */
306
+ axis?: string;
307
+ /** An abscissa in the x axis' own terms (a category, a Date) for `axis: "x"`, a
308
+ * number on that axis otherwise. A category the rows do not have draws nothing. */
309
+ value: SeriesChartXValue;
310
+ /** Written along the line, inside the plot at its top-left. SVG text: a string. */
311
+ label?: string;
312
+ /** Default `"muted"`. `color` wins over it. */
313
+ tone?: SeriesChartTone;
314
+ color?: string;
315
+ /** Which of `STROKE_PATTERNS`. Default 1, dashed: a reference is not data, and a
316
+ * solid line reads as a series nobody put in the legend. */
317
+ dash?: number;
318
+ }
319
+ /**
320
+ * A single labelled point — today's figure on keksdose's cash buffer, the month the
321
+ * projection runs dry. For a mark on EVERY sample, or on the samples that meet a test,
322
+ * use the series' `dot` instead; a marker is for a point that is a fact of its own.
323
+ * Fitted like a reference: it widens the band it would otherwise fall outside of.
324
+ */
325
+ interface SeriesChartMarker {
326
+ /** Distinct within the chart. Default: its position in the list. */
327
+ key?: string;
328
+ /** In the x axis' own terms, like a reference's `value`. */
329
+ x: SeriesChartXValue;
330
+ y: number;
331
+ /** The y axis `y` is measured on. Default `"y"`. */
332
+ axis?: string;
333
+ /** Written above the point. */
334
+ label?: string;
335
+ /** Default `"brand"`. `color` wins over it. */
336
+ tone?: SeriesChartTone;
337
+ color?: string;
338
+ /** Radius in px. Default 4.5. */
339
+ r?: number;
340
+ }
341
+ /** What a click on the plot picked. */
342
+ interface SeriesChartHit {
343
+ /** The row's position in `rows`. */
344
+ index: number;
345
+ /** The caller's own row — with its `rawPeriod`, id or whatever the drilldown needs. */
346
+ row: SeriesChartRow;
347
+ x: SeriesChartXValue;
348
+ /** The series, when the click landed ON a bar. A click anywhere else picks the slot
349
+ * (the period), not a series. */
350
+ key?: string;
351
+ }
102
352
  interface SeriesChartProps {
103
353
  /** One row per abscissa value. A missing key is a hole (see `connectNulls`). */
104
- rows: Record<string, number>[];
354
+ rows: readonly SeriesChartRow[];
105
355
  series: SeriesChartSeries[];
106
356
  /** Default: one untitled axis, `"y"`. */
107
357
  axes?: SeriesChartAxis[];
@@ -109,9 +359,13 @@ interface SeriesChartProps {
109
359
  /** A value in the tooltip, where a number stands on its own and needs its unit.
110
360
  * Default: `Intl.NumberFormat` in the kit's locale. */
111
361
  valueFormat?: (value: number) => string;
112
- /** Tailwind height class. Default `h-72`. The empty state takes it too, so a chart
113
- * losing its last line does not relayout the page under it. */
114
- height?: string;
362
+ /** Tailwind height class, or a height in pixels. Default `h-72`. The empty state
363
+ * takes it too, so a chart losing its last line does not relayout the page under it.
364
+ * A number is for a height the caller holds as a number — keksdose's report charts
365
+ * take `height = 260` as a prop and wrap the chart in a `SizedSeriesChart` div
366
+ * (reports/charts/networth-line.tsx) only to turn it into a style, since a class
367
+ * cannot be built from a number Tailwind never saw. */
368
+ height?: string | number;
115
369
  /** Bridge holes left by sources sampled on different grids. See {@link mergeSeries}. */
116
370
  connectNulls?: boolean;
117
371
  /** Shown, centred at the chart's height, instead of an empty chart. Default: the
@@ -124,6 +378,26 @@ interface SeriesChartProps {
124
378
  */
125
379
  animationMs?: number;
126
380
  spans?: SeriesChartSpan[];
381
+ /** Lines across the plot at one value. */
382
+ references?: SeriesChartReference[];
383
+ /** Single labelled points. */
384
+ markers?: SeriesChartMarker[];
385
+ /**
386
+ * Which axes a drag may zoom: `"both"`, `"x"`, `"y"` or `"none"`. Default: read off
387
+ * the marks — see `defaultZoomAxes` (lines both, areas x, bars none). An axis carrying
388
+ * bars or areas never takes a DRAGGED y window: it refits to the x window, from zero.
389
+ * Ignored by `StaticSeriesChart`, which does not zoom.
390
+ */
391
+ zoomAxes?: ZoomAxesSetting;
392
+ /**
393
+ * A click on the plot: the slot under the pointer, and the series when it landed on a
394
+ * bar. keksdose's drilldowns — a payee's month, a budget line, a spending category.
395
+ * A drag that zoomed is not a click.
396
+ */
397
+ onPointClick?: (hit: SeriesChartHit) => void;
398
+ /** Where the tooltip may go: for a chart inside a scroll wrapper. See
399
+ * {@link SeriesChartTooltip}. */
400
+ tooltip?: SeriesChartTooltip;
127
401
  /** Supplied by `withChartZoom` and by nothing else. */
128
402
  zoom?: ZoomBinding;
129
403
  /** Per-chart strings over `<UiKitProvider labels={{ seriesChart }}>`. */
@@ -188,20 +462,41 @@ declare function mergeSeries(sources: SeriesSource[]): Record<string, number>[];
188
462
  * a digit or a hyphen gets a leading `_`.
189
463
  */
190
464
  declare function seriesKey(...parts: (string | number)[]): string;
465
+ /**
466
+ * The band an axis carrying bars or areas draws: the data's extent with ZERO in it,
467
+ * padded only on the sides that are not zero — bars standing on a frame's bottom edge,
468
+ * not floating four per cent above it on a band of air nobody asked for.
469
+ * `undefined` when there is nothing to fit.
470
+ */
471
+ declare function anchoredBand(extent: readonly [number, number] | undefined): [number, number] | undefined;
472
+ /**
473
+ * Series with their colours settled BEFORE any are switched off.
474
+ *
475
+ * A series with no `color` takes `paletteFor(its position)` — and a legend toggle that
476
+ * hands the chart a shorter list moves every later series one position up, repainting
477
+ * it in its neighbour's colour on each click. Resolving the colours on the full list
478
+ * and filtering after keeps each series in the colour its legend entry shows.
479
+ */
480
+ declare function visibleSeries(series: readonly SeriesChartSeries[], hidden: ReadonlySet<string>): SeriesChartSeries[];
481
+ /**
482
+ * The `ToggleLegend` entries for a chart's FULL series list — colours resolved the way
483
+ * the chart resolves them, and a stroke mark for a line drawn in a pattern (dashed,
484
+ * step) so the key promises the stroke the plot draws. A bar or an area is a swatch.
485
+ * Pair with {@link visibleSeries} for the chart itself.
486
+ */
487
+ declare function seriesLegendEntries(series: readonly SeriesChartSeries[]): LegendEntry[];
191
488
  /**
192
489
  * {@link SeriesChart} without the zoom: the same picture, no drag layer, no reset
193
490
  * button. For a thumbnail, a print view, or a chart the consumer wraps in its own
194
491
  * interaction.
195
492
  */
196
- declare function StaticSeriesChart({ rows, x, series, axes, valueFormat, height, connectNulls, empty, animationMs, spans, zoom, labels: labelsProp, locale, className, }: SeriesChartProps): react.JSX.Element;
493
+ declare function StaticSeriesChart(props: SeriesChartProps): react.JSX.Element;
197
494
  /**
198
495
  * The series chart, zoomable. Drag across the plot to zoom (the drag's shape picks the
199
496
  * axes), double-click or press the reset button to go back; wrap several in
200
- * `SharedXZoom` to move their x windows together.
497
+ * `SharedXZoom` to move their x windows together. Which axes zoom depends on the marks
498
+ * — see {@link SeriesChartProps.zoomAxes}.
201
499
  */
202
- declare const SeriesChart: {
203
- (props: SeriesChartProps): react.JSX.Element;
204
- displayName: string;
205
- };
500
+ declare function SeriesChart(props: SeriesChartProps): react.JSX.Element;
206
501
 
207
- export { AXIS_TICK_WIDTH, AXIS_TITLE_STRIP, SeriesChart, type SeriesChartAxis, type SeriesChartProps, type SeriesChartSeries, type SeriesChartSpan, type SeriesChartX, type SeriesSource, StaticSeriesChart, axisBandWidth, mergeSeries, oneAxis, padBand, paddedDomain, seriesKey, soleSeriesColor };
502
+ export { AXIS_TICK_WIDTH, AXIS_TITLE_STRIP, SeriesChart, type SeriesChartAxis, type SeriesChartHit, type SeriesChartMarker, type SeriesChartPoint, type SeriesChartProps, type SeriesChartReference, type SeriesChartRow, type SeriesChartSeries, type SeriesChartSpan, type SeriesChartTickValues, type SeriesChartTone, type SeriesChartTooltip, type SeriesChartType, type SeriesChartX, type SeriesChartXTick, type SeriesChartXValue, type SeriesSource, StaticSeriesChart, TimeTickUnit, anchoredBand, axisBandWidth, mergeSeries, oneAxis, padBand, paddedDomain, seriesKey, seriesLegendEntries, soleSeriesColor, visibleSeries };