@sckyzo/cosmos-charts 0.3.0 → 0.4.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 (79) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +12 -1
  3. package/dist/BarChart.cjs +18 -18
  4. package/dist/BarChart.js +5 -5
  5. package/dist/BoxPlotChart.cjs +18 -18
  6. package/dist/BoxPlotChart.js +5 -5
  7. package/dist/BumpChart.cjs +6 -6
  8. package/dist/BumpChart.js +3 -3
  9. package/dist/CalendarChart.cjs +9 -7
  10. package/dist/CalendarChart.cjs.map +1 -1
  11. package/dist/CalendarChart.js +5 -3
  12. package/dist/CalendarChart.js.map +1 -1
  13. package/dist/DonutChart.cjs +8 -8
  14. package/dist/DonutChart.js +3 -3
  15. package/dist/FunnelChart.cjs +8 -6
  16. package/dist/FunnelChart.cjs.map +1 -1
  17. package/dist/FunnelChart.js +4 -2
  18. package/dist/FunnelChart.js.map +1 -1
  19. package/dist/GradientRadial.cjs +3 -3
  20. package/dist/GradientRadial.js +2 -2
  21. package/dist/HeatmapChart.cjs +8 -6
  22. package/dist/HeatmapChart.cjs.map +1 -1
  23. package/dist/HeatmapChart.js +5 -3
  24. package/dist/HeatmapChart.js.map +1 -1
  25. package/dist/LineAreaChart.cjs +13 -13
  26. package/dist/LineAreaChart.js +4 -4
  27. package/dist/MixedChart.cjs +16 -16
  28. package/dist/MixedChart.js +5 -5
  29. package/dist/RadarChart.cjs +9 -9
  30. package/dist/RadarChart.js +3 -3
  31. package/dist/RadialBarChart.cjs +3 -3
  32. package/dist/RadialBarChart.js +1 -1
  33. package/dist/RangeBarChart.cjs +13 -13
  34. package/dist/RangeBarChart.js +4 -4
  35. package/dist/RealtimeChart.cjs +8 -8
  36. package/dist/RealtimeChart.js +2 -2
  37. package/dist/ScatterChart.cjs +12 -12
  38. package/dist/ScatterChart.js +4 -4
  39. package/dist/SemiCircleGauge.cjs +2 -2
  40. package/dist/SemiCircleGauge.js +1 -1
  41. package/dist/Sparkline.cjs +4 -4
  42. package/dist/Sparkline.js +1 -1
  43. package/dist/StrokedGauge.cjs +3 -3
  44. package/dist/StrokedGauge.js +2 -2
  45. package/dist/TreemapChart.cjs +2 -2
  46. package/dist/TreemapChart.js +1 -1
  47. package/dist/WaterfallChart.cjs +12 -12
  48. package/dist/WaterfallChart.js +3 -3
  49. package/dist/{chunk-6ALKZLN2.js → chunk-4AKHZNWP.js} +3 -3
  50. package/dist/{chunk-6ALKZLN2.js.map → chunk-4AKHZNWP.js.map} +1 -1
  51. package/dist/{chunk-3N43QT36.js → chunk-56WD3OHA.js} +6 -4
  52. package/dist/chunk-56WD3OHA.js.map +1 -0
  53. package/dist/{chunk-YWYF5CCJ.js → chunk-6FGJZBTC.js} +3 -3
  54. package/dist/{chunk-YWYF5CCJ.js.map → chunk-6FGJZBTC.js.map} +1 -1
  55. package/dist/{chunk-MN4CDVOS.cjs → chunk-CMBNNLIV.cjs} +4 -4
  56. package/dist/{chunk-MN4CDVOS.cjs.map → chunk-CMBNNLIV.cjs.map} +1 -1
  57. package/dist/{chunk-RILUG7JB.js → chunk-DI2FBGKM.js} +3 -3
  58. package/dist/{chunk-RILUG7JB.js.map → chunk-DI2FBGKM.js.map} +1 -1
  59. package/dist/{chunk-SGG7XKOY.js → chunk-ESVGCUJN.js} +3 -3
  60. package/dist/{chunk-SGG7XKOY.js.map → chunk-ESVGCUJN.js.map} +1 -1
  61. package/dist/{chunk-RLHGPHC7.cjs → chunk-G4WOPX4D.cjs} +4 -4
  62. package/dist/{chunk-RLHGPHC7.cjs.map → chunk-G4WOPX4D.cjs.map} +1 -1
  63. package/dist/{chunk-GZRMVE4X.cjs → chunk-RCDTBZC2.cjs} +4 -4
  64. package/dist/{chunk-GZRMVE4X.cjs.map → chunk-RCDTBZC2.cjs.map} +1 -1
  65. package/dist/{chunk-6NRRABPF.cjs → chunk-SR2ESX3R.cjs} +6 -4
  66. package/dist/chunk-SR2ESX3R.cjs.map +1 -0
  67. package/dist/{chunk-ICL5K2CW.js → chunk-UL3SNXQR.js} +3 -3
  68. package/dist/{chunk-ICL5K2CW.js.map → chunk-UL3SNXQR.js.map} +1 -1
  69. package/dist/{chunk-6BKLL7LZ.cjs → chunk-XMFBVMW7.cjs} +4 -4
  70. package/dist/{chunk-6BKLL7LZ.cjs.map → chunk-XMFBVMW7.cjs.map} +1 -1
  71. package/dist/{chunk-Z4LZFMDH.cjs → chunk-XUGQ6VXO.cjs} +4 -4
  72. package/dist/{chunk-Z4LZFMDH.cjs.map → chunk-XUGQ6VXO.cjs.map} +1 -1
  73. package/dist/{chunk-HMH6DI7U.js → chunk-YMRNTIOK.js} +3 -3
  74. package/dist/{chunk-HMH6DI7U.js.map → chunk-YMRNTIOK.js.map} +1 -1
  75. package/dist/{chunk-TPH5T3DA.cjs → chunk-ZWHCUYIN.cjs} +4 -4
  76. package/dist/{chunk-TPH5T3DA.cjs.map → chunk-ZWHCUYIN.cjs.map} +1 -1
  77. package/package.json +1 -1
  78. package/dist/chunk-3N43QT36.js.map +0 -1
  79. package/dist/chunk-6NRRABPF.cjs.map +0 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,20 @@ All notable changes to `@sckyzo/cosmos-charts` are documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.4.0](https://github.com/SckyzO/cosmos/compare/@sckyzo/cosmos-charts@0.3.1...@sckyzo/cosmos-charts@0.4.0) (2026-10-30)
9
+
10
+
11
+ ### Documentation
12
+
13
+ * **charts:** add the `@source` line to the install steps ([80f1687](https://github.com/SckyzO/cosmos/commit/80f16872bb9e68ad13924034a15eb6d2a123695b))
14
+
15
+ ## [0.3.1](https://github.com/SckyzO/cosmos/compare/@sckyzo/cosmos-charts@0.3.0...@sckyzo/cosmos-charts@0.3.1) (2026-10-30)
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * **charts:** keep the charts left to right under dir=rtl ([d9c5d80](https://github.com/SckyzO/cosmos/commit/d9c5d806a6f3718b369719ed8198681ea4116c35))
21
+
8
22
  ## [0.3.0](https://github.com/SckyzO/cosmos/compare/@sckyzo/cosmos-charts@0.2.0...@sckyzo/cosmos-charts@0.3.0) (2026-10-27)
9
23
 
10
24
 
package/README.md CHANGED
@@ -15,6 +15,17 @@ pnpm add @sckyzo/cosmos-charts
15
15
  pnpm add react react-dom # peers, react 19+
16
16
  ```
17
17
 
18
+ A few charts carry Tailwind 4 classes: the legend's focus ring, the calendar's shades in a dark
19
+ theme. Point Tailwind at this package too, in the CSS file that imports it, next to the `@source`
20
+ line for `@sckyzo/cosmos-react`. Without it, those classes are not generated.
21
+
22
+ ```css
23
+ @source '../node_modules/@sckyzo/cosmos-charts/dist/**/*.{js,cjs}';
24
+ ```
25
+
26
+ From 0.4.0, the three Cosmos packages share one version number: install the same version of
27
+ `@sckyzo/cosmos-charts` as of `@sckyzo/cosmos-react` and `@sckyzo/cosmos-theme`.
28
+
18
29
  ## How the charts are drawn
19
30
 
20
31
  Every chart is drawn with Recharts, except `HeatmapChart` and `FunnelChart`, drawn in HTML and SVG (Recharts has no heatmap, and its bars cannot be joined by a flow), and `WorldMap`, an SVG of its own (Recharts has no map). The rules every chart follows:
@@ -96,7 +107,7 @@ The scale has five steps of the accent, cut by quantiles of the values so that e
96
107
 
97
108
  `RadarChart` draws its polygons as large as its box allows and leaves the scale (0, 20 … 100) off them unless given `showScale`. `DonutChart` writes the total in the middle, and the value and name of the slice under the pointer in its place (`centerValue` and `centerLabel` replace the sum and "Total"; `variant="pie"` fills the disc and writes nothing in it; `legendValues` adds each slice's value and its share, in whole percents that add up to 100, to the legend, in columns when the legend is on a side); `RadialBarChart` does the same with the average and the ring.
98
109
 
99
- The charts that draw a legend take `legendPosition` (`top`, `right`, `bottom` or `left`): the legend sits above the plot by default, below the donut on `DonutChart`.
110
+ The charts that draw a legend take `legendPosition` (`top`, `right`, `bottom` or `left`): the legend sits above the plot by default, below the donut on `DonutChart`. `left` and `right` are the sides of the screen, not of the line: a chart keeps its left-to-right axis in a right-to-left page, and its legend stays where you put it.
100
111
 
101
112
  A chart with no series, or only empty ones, draws `emptyMessage` (default `No data`, an empty string for nothing) in place of the plot. The gauges, which always have a value, and `RealtimeChart`, which fills its own window, have no such prop.
102
113
 
package/dist/BarChart.cjs CHANGED
@@ -3,14 +3,14 @@
3
3
 
4
4
  var chunkGVTMZYOM_cjs = require('./chunk-GVTMZYOM.cjs');
5
5
  var chunkF2PMFYJ5_cjs = require('./chunk-F2PMFYJ5.cjs');
6
- var chunkZ4LZFMDH_cjs = require('./chunk-Z4LZFMDH.cjs');
7
- var chunk6BKLL7LZ_cjs = require('./chunk-6BKLL7LZ.cjs');
8
- var chunkGZRMVE4X_cjs = require('./chunk-GZRMVE4X.cjs');
6
+ var chunkXUGQ6VXO_cjs = require('./chunk-XUGQ6VXO.cjs');
7
+ var chunkXMFBVMW7_cjs = require('./chunk-XMFBVMW7.cjs');
8
+ var chunkRCDTBZC2_cjs = require('./chunk-RCDTBZC2.cjs');
9
9
  var chunkTYQWZR3S_cjs = require('./chunk-TYQWZR3S.cjs');
10
- var chunkRLHGPHC7_cjs = require('./chunk-RLHGPHC7.cjs');
10
+ var chunkG4WOPX4D_cjs = require('./chunk-G4WOPX4D.cjs');
11
11
  var chunkT3K6Q34U_cjs = require('./chunk-T3K6Q34U.cjs');
12
12
  var chunkK3R7JGOW_cjs = require('./chunk-K3R7JGOW.cjs');
13
- var chunk6NRRABPF_cjs = require('./chunk-6NRRABPF.cjs');
13
+ var chunkSR2ESX3R_cjs = require('./chunk-SR2ESX3R.cjs');
14
14
  var chunkLT3UC65O_cjs = require('./chunk-LT3UC65O.cjs');
15
15
  var recharts = require('recharts');
16
16
  var jsxRuntime = require('react/jsx-runtime');
@@ -38,12 +38,12 @@ var BarChart = ({
38
38
  height = 320,
39
39
  width
40
40
  }) => {
41
- const hidden = chunkGZRMVE4X_cjs.useHiddenSeries();
42
- const axis = chunkRLHGPHC7_cjs.useAxis();
41
+ const hidden = chunkRCDTBZC2_cjs.useHiddenSeries();
42
+ const axis = chunkG4WOPX4D_cjs.useAxis();
43
43
  const categoryKeys = chunkF2PMFYJ5_cjs.useCategoryKeys(orientation === "horizontal" ? "vertical" : "horizontal");
44
44
  const name = ariaLabel ?? `Bar chart: ${series.map((s) => s.name).join(", ")}`;
45
45
  if (chunkK3R7JGOW_cjs.hasNoData(series)) {
46
- return /* @__PURE__ */ jsxRuntime.jsx(chunk6NRRABPF_cjs.ChartEmpty, { message: emptyMessage, ariaLabel: name, height, width });
46
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkSR2ESX3R_cjs.ChartEmpty, { message: emptyMessage, ariaLabel: name, height, width });
47
47
  }
48
48
  const horizontal = orientation === "horizontal";
49
49
  const layout = horizontal ? "vertical" : "horizontal";
@@ -53,7 +53,7 @@ var BarChart = ({
53
53
  recharts.BarChart,
54
54
  {
55
55
  ref: categoryKeys,
56
- ...chunk6NRRABPF_cjs.frameProps({ height, width, ariaLabel: name }),
56
+ ...chunkSR2ESX3R_cjs.frameProps({ height, width, ariaLabel: name }),
57
57
  data: chunkK3R7JGOW_cjs.toRows(categories, series),
58
58
  layout,
59
59
  stackOffset: "sign",
@@ -64,21 +64,21 @@ var BarChart = ({
64
64
  /* @__PURE__ */ jsxRuntime.jsx(
65
65
  recharts.CartesianGrid,
66
66
  {
67
- ...chunkRLHGPHC7_cjs.GRID_PROPS,
67
+ ...chunkG4WOPX4D_cjs.GRID_PROPS,
68
68
  ...horizontal ? { horizontal: false, vertical: true } : {}
69
69
  }
70
70
  ),
71
71
  horizontal ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
72
- /* @__PURE__ */ jsxRuntime.jsx(recharts.XAxis, { type: "number", tickFormatter: formatValue, ...axis, ...chunkRLHGPHC7_cjs.xAxisTitle(xTitle) }),
72
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.XAxis, { type: "number", tickFormatter: formatValue, ...axis, ...chunkG4WOPX4D_cjs.xAxisTitle(xTitle) }),
73
73
  /* @__PURE__ */ jsxRuntime.jsx(
74
74
  recharts.YAxis,
75
75
  {
76
76
  type: "category",
77
77
  dataKey: "category",
78
78
  width: "auto",
79
- tickFormatter: chunk6BKLL7LZ_cjs.trimLabel,
79
+ tickFormatter: chunkXMFBVMW7_cjs.trimLabel,
80
80
  ...axis,
81
- ...chunkRLHGPHC7_cjs.yAxisTitle(yTitle)
81
+ ...chunkG4WOPX4D_cjs.yAxisTitle(yTitle)
82
82
  }
83
83
  )
84
84
  ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
@@ -87,13 +87,13 @@ var BarChart = ({
87
87
  {
88
88
  dataKey: "category",
89
89
  ...axis,
90
- ...chunkRLHGPHC7_cjs.xAxisTitle(xTitle),
91
- ...chunk6BKLL7LZ_cjs.categoryAxis(categories, xTitle)
90
+ ...chunkG4WOPX4D_cjs.xAxisTitle(xTitle),
91
+ ...chunkXMFBVMW7_cjs.categoryAxis(categories, xTitle)
92
92
  }
93
93
  ),
94
- /* @__PURE__ */ jsxRuntime.jsx(recharts.YAxis, { width: "auto", tickFormatter: formatValue, ...axis, ...chunkRLHGPHC7_cjs.yAxisTitle(yTitle) })
94
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.YAxis, { width: "auto", tickFormatter: formatValue, ...axis, ...chunkG4WOPX4D_cjs.yAxisTitle(yTitle) })
95
95
  ] }),
96
- (showLegend ?? series.length > 1) && /* @__PURE__ */ jsxRuntime.jsx(recharts.Legend, { ...chunkGZRMVE4X_cjs.legendProps(legendPosition, hidden) }),
96
+ (showLegend ?? series.length > 1) && /* @__PURE__ */ jsxRuntime.jsx(recharts.Legend, { ...chunkRCDTBZC2_cjs.legendProps(legendPosition, hidden) }),
97
97
  /* @__PURE__ */ jsxRuntime.jsx(
98
98
  recharts.Tooltip,
99
99
  {
@@ -125,7 +125,7 @@ var BarChart = ({
125
125
  key
126
126
  );
127
127
  }),
128
- chunkZ4LZFMDH_cjs.referenceMarks({ referenceLines, referenceBands, axis: horizontal ? "x" : "y" }),
128
+ chunkXUGQ6VXO_cjs.referenceMarks({ referenceLines, referenceBands, axis: horizontal ? "x" : "y" }),
129
129
  children
130
130
  ]
131
131
  }
package/dist/BarChart.js CHANGED
@@ -1,14 +1,14 @@
1
1
  "use client";
2
2
  import { roundedBarShape, isOuterInStack } from './chunk-GDZLYYL2.js';
3
3
  import { useCategoryKeys } from './chunk-FUZW3H5X.js';
4
- import { referenceMarks } from './chunk-SGG7XKOY.js';
5
- import { trimLabel, categoryAxis } from './chunk-HMH6DI7U.js';
6
- import { useHiddenSeries, legendProps } from './chunk-6ALKZLN2.js';
4
+ import { referenceMarks } from './chunk-ESVGCUJN.js';
5
+ import { trimLabel, categoryAxis } from './chunk-YMRNTIOK.js';
6
+ import { useHiddenSeries, legendProps } from './chunk-4AKHZNWP.js';
7
7
  import { ANIMATION } from './chunk-5C2RLJYZ.js';
8
- import { useAxis, GRID_PROPS, xAxisTitle, yAxisTitle } from './chunk-RILUG7JB.js';
8
+ import { useAxis, GRID_PROPS, xAxisTitle, yAxisTitle } from './chunk-DI2FBGKM.js';
9
9
  import { ChartTooltip } from './chunk-VIOSQN4Z.js';
10
10
  import { hasNoData, seriesKey, toRows } from './chunk-UJIV5PVI.js';
11
- import { ChartEmpty, frameProps } from './chunk-3N43QT36.js';
11
+ import { ChartEmpty, frameProps } from './chunk-56WD3OHA.js';
12
12
  import { BORDER, seriesColor } from './chunk-UATB2IRY.js';
13
13
  import { BarChart as BarChart$1, CartesianGrid, XAxis, YAxis, Legend, Tooltip, Bar } from 'recharts';
14
14
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -2,14 +2,14 @@
2
2
  'use strict';
3
3
 
4
4
  var chunkF2PMFYJ5_cjs = require('./chunk-F2PMFYJ5.cjs');
5
- var chunkZ4LZFMDH_cjs = require('./chunk-Z4LZFMDH.cjs');
6
- var chunk6BKLL7LZ_cjs = require('./chunk-6BKLL7LZ.cjs');
7
- var chunkGZRMVE4X_cjs = require('./chunk-GZRMVE4X.cjs');
5
+ var chunkXUGQ6VXO_cjs = require('./chunk-XUGQ6VXO.cjs');
6
+ var chunkXMFBVMW7_cjs = require('./chunk-XMFBVMW7.cjs');
7
+ var chunkRCDTBZC2_cjs = require('./chunk-RCDTBZC2.cjs');
8
8
  var chunkTYQWZR3S_cjs = require('./chunk-TYQWZR3S.cjs');
9
- var chunkRLHGPHC7_cjs = require('./chunk-RLHGPHC7.cjs');
9
+ var chunkG4WOPX4D_cjs = require('./chunk-G4WOPX4D.cjs');
10
10
  var chunkT3K6Q34U_cjs = require('./chunk-T3K6Q34U.cjs');
11
11
  var chunkK3R7JGOW_cjs = require('./chunk-K3R7JGOW.cjs');
12
- var chunk6NRRABPF_cjs = require('./chunk-6NRRABPF.cjs');
12
+ var chunkSR2ESX3R_cjs = require('./chunk-SR2ESX3R.cjs');
13
13
  var chunkLT3UC65O_cjs = require('./chunk-LT3UC65O.cjs');
14
14
  var recharts = require('recharts');
15
15
  var jsxRuntime = require('react/jsx-runtime');
@@ -80,12 +80,12 @@ var BoxPlotChart = ({
80
80
  height = 320,
81
81
  width
82
82
  }) => {
83
- const hidden = chunkGZRMVE4X_cjs.useHiddenSeries();
84
- const axis = chunkRLHGPHC7_cjs.useAxis();
83
+ const hidden = chunkRCDTBZC2_cjs.useHiddenSeries();
84
+ const axis = chunkG4WOPX4D_cjs.useAxis();
85
85
  const categoryKeys = chunkF2PMFYJ5_cjs.useCategoryKeys(orientation === "horizontal" ? "vertical" : "horizontal");
86
86
  const name = ariaLabel ?? `Box plot: ${series.map((s) => s.name).join(", ")}`;
87
87
  if (chunkK3R7JGOW_cjs.hasNoData(series)) {
88
- return /* @__PURE__ */ jsxRuntime.jsx(chunk6NRRABPF_cjs.ChartEmpty, { message: emptyMessage, ariaLabel: name, height, width });
88
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkSR2ESX3R_cjs.ChartEmpty, { message: emptyMessage, ariaLabel: name, height, width });
89
89
  }
90
90
  const horizontal = orientation === "horizontal";
91
91
  const rows = categories.map((category, i) => ({
@@ -122,7 +122,7 @@ var BoxPlotChart = ({
122
122
  recharts.BarChart,
123
123
  {
124
124
  ref: categoryKeys,
125
- ...chunk6NRRABPF_cjs.frameProps({ height, width, ariaLabel: name }),
125
+ ...chunkSR2ESX3R_cjs.frameProps({ height, width, ariaLabel: name }),
126
126
  data: rows,
127
127
  layout: horizontal ? "vertical" : "horizontal",
128
128
  margin: { top: 4, right: 12, bottom: 0, left: 0 },
@@ -132,7 +132,7 @@ var BoxPlotChart = ({
132
132
  /* @__PURE__ */ jsxRuntime.jsx(
133
133
  recharts.CartesianGrid,
134
134
  {
135
- ...chunkRLHGPHC7_cjs.GRID_PROPS,
135
+ ...chunkG4WOPX4D_cjs.GRID_PROPS,
136
136
  ...horizontal ? { horizontal: false, vertical: true } : {}
137
137
  }
138
138
  ),
@@ -144,7 +144,7 @@ var BoxPlotChart = ({
144
144
  domain: ["auto", "auto"],
145
145
  tickFormatter: formatValue,
146
146
  ...axis,
147
- ...chunkRLHGPHC7_cjs.xAxisTitle(xTitle)
147
+ ...chunkG4WOPX4D_cjs.xAxisTitle(xTitle)
148
148
  }
149
149
  ),
150
150
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -153,9 +153,9 @@ var BoxPlotChart = ({
153
153
  type: "category",
154
154
  dataKey: "category",
155
155
  width: "auto",
156
- tickFormatter: chunk6BKLL7LZ_cjs.trimLabel,
156
+ tickFormatter: chunkXMFBVMW7_cjs.trimLabel,
157
157
  ...axis,
158
- ...chunkRLHGPHC7_cjs.yAxisTitle(yTitle)
158
+ ...chunkG4WOPX4D_cjs.yAxisTitle(yTitle)
159
159
  }
160
160
  )
161
161
  ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
@@ -164,8 +164,8 @@ var BoxPlotChart = ({
164
164
  {
165
165
  dataKey: "category",
166
166
  ...axis,
167
- ...chunkRLHGPHC7_cjs.xAxisTitle(xTitle),
168
- ...chunk6BKLL7LZ_cjs.categoryAxis(categories, xTitle)
167
+ ...chunkG4WOPX4D_cjs.xAxisTitle(xTitle),
168
+ ...chunkXMFBVMW7_cjs.categoryAxis(categories, xTitle)
169
169
  }
170
170
  ),
171
171
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -176,11 +176,11 @@ var BoxPlotChart = ({
176
176
  width: "auto",
177
177
  tickFormatter: formatValue,
178
178
  ...axis,
179
- ...chunkRLHGPHC7_cjs.yAxisTitle(yTitle)
179
+ ...chunkG4WOPX4D_cjs.yAxisTitle(yTitle)
180
180
  }
181
181
  )
182
182
  ] }),
183
- (showLegend ?? series.length > 1) && /* @__PURE__ */ jsxRuntime.jsx(recharts.Legend, { ...chunkGZRMVE4X_cjs.legendProps(legendPosition, hidden) }),
183
+ (showLegend ?? series.length > 1) && /* @__PURE__ */ jsxRuntime.jsx(recharts.Legend, { ...chunkRCDTBZC2_cjs.legendProps(legendPosition, hidden) }),
184
184
  /* @__PURE__ */ jsxRuntime.jsx(
185
185
  recharts.Tooltip,
186
186
  {
@@ -202,7 +202,7 @@ var BoxPlotChart = ({
202
202
  },
203
203
  chunkK3R7JGOW_cjs.seriesKey(index)
204
204
  )),
205
- chunkZ4LZFMDH_cjs.referenceMarks({ referenceLines, referenceBands, axis: horizontal ? "x" : "y" }),
205
+ chunkXUGQ6VXO_cjs.referenceMarks({ referenceLines, referenceBands, axis: horizontal ? "x" : "y" }),
206
206
  children
207
207
  ]
208
208
  }
@@ -1,13 +1,13 @@
1
1
  "use client";
2
2
  import { useCategoryKeys } from './chunk-FUZW3H5X.js';
3
- import { referenceMarks } from './chunk-SGG7XKOY.js';
4
- import { trimLabel, categoryAxis } from './chunk-HMH6DI7U.js';
5
- import { useHiddenSeries, legendProps } from './chunk-6ALKZLN2.js';
3
+ import { referenceMarks } from './chunk-ESVGCUJN.js';
4
+ import { trimLabel, categoryAxis } from './chunk-YMRNTIOK.js';
5
+ import { useHiddenSeries, legendProps } from './chunk-4AKHZNWP.js';
6
6
  import { ANIMATION } from './chunk-5C2RLJYZ.js';
7
- import { useAxis, GRID_PROPS, xAxisTitle, yAxisTitle } from './chunk-RILUG7JB.js';
7
+ import { useAxis, GRID_PROPS, xAxisTitle, yAxisTitle } from './chunk-DI2FBGKM.js';
8
8
  import { TooltipCard } from './chunk-VIOSQN4Z.js';
9
9
  import { hasNoData, seriesKey } from './chunk-UJIV5PVI.js';
10
- import { ChartEmpty, frameProps } from './chunk-3N43QT36.js';
10
+ import { ChartEmpty, frameProps } from './chunk-56WD3OHA.js';
11
11
  import { BORDER, seriesColor } from './chunk-UATB2IRY.js';
12
12
  import { BarChart, CartesianGrid, XAxis, YAxis, Legend, Tooltip, Bar } from 'recharts';
13
13
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -1,13 +1,13 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var chunk6BKLL7LZ_cjs = require('./chunk-6BKLL7LZ.cjs');
4
+ var chunkXMFBVMW7_cjs = require('./chunk-XMFBVMW7.cjs');
5
5
  var chunkIW6EWB26_cjs = require('./chunk-IW6EWB26.cjs');
6
6
  var chunkTYQWZR3S_cjs = require('./chunk-TYQWZR3S.cjs');
7
- var chunkRLHGPHC7_cjs = require('./chunk-RLHGPHC7.cjs');
7
+ var chunkG4WOPX4D_cjs = require('./chunk-G4WOPX4D.cjs');
8
8
  var chunkT3K6Q34U_cjs = require('./chunk-T3K6Q34U.cjs');
9
9
  var chunkK3R7JGOW_cjs = require('./chunk-K3R7JGOW.cjs');
10
- var chunk6NRRABPF_cjs = require('./chunk-6NRRABPF.cjs');
10
+ var chunkSR2ESX3R_cjs = require('./chunk-SR2ESX3R.cjs');
11
11
  var chunkLT3UC65O_cjs = require('./chunk-LT3UC65O.cjs');
12
12
  var react = require('react');
13
13
  var recharts = require('recharts');
@@ -136,7 +136,7 @@ var BumpChart = ({
136
136
  [periods, plotted]
137
137
  );
138
138
  if (chunkK3R7JGOW_cjs.hasNoData(series) || periods.length === 0) {
139
- return /* @__PURE__ */ jsxRuntime.jsx(chunk6NRRABPF_cjs.ChartEmpty, { message: emptyMessage, ariaLabel: name, height, width });
139
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkSR2ESX3R_cjs.ChartEmpty, { message: emptyMessage, ariaLabel: name, height, width });
140
140
  }
141
141
  const compact = measured !== void 0 && measured < COMPACT_BELOW;
142
142
  const chars = compact ? NAME_CHARS.compact : NAME_CHARS.wide;
@@ -272,11 +272,11 @@ var BumpChart = ({
272
272
  children: /* @__PURE__ */ jsxRuntime.jsxs(
273
273
  recharts.LineChart,
274
274
  {
275
- ...chunk6NRRABPF_cjs.frameProps({ height, width: "100%", ariaLabel: name }),
275
+ ...chunkSR2ESX3R_cjs.frameProps({ height, width: "100%", ariaLabel: name }),
276
276
  data: rows,
277
277
  margin,
278
278
  children: [
279
- /* @__PURE__ */ jsxRuntime.jsx(recharts.XAxis, { dataKey: "category", ...chunkRLHGPHC7_cjs.AXIS, ...chunk6BKLL7LZ_cjs.categoryAxis(periods) }),
279
+ /* @__PURE__ */ jsxRuntime.jsx(recharts.XAxis, { dataKey: "category", ...chunkG4WOPX4D_cjs.AXIS, ...chunkXMFBVMW7_cjs.categoryAxis(periods) }),
280
280
  /* @__PURE__ */ jsxRuntime.jsx(recharts.YAxis, { hide: true, type: "number", reversed: true, domain }),
281
281
  /* @__PURE__ */ jsxRuntime.jsx(
282
282
  recharts.Tooltip,
package/dist/BumpChart.js CHANGED
@@ -1,11 +1,11 @@
1
1
  "use client";
2
- import { categoryAxis } from './chunk-HMH6DI7U.js';
2
+ import { categoryAxis } from './chunk-YMRNTIOK.js';
3
3
  import { useElementWidth } from './chunk-AOSO5QHL.js';
4
4
  import { ANIMATION } from './chunk-5C2RLJYZ.js';
5
- import { AXIS } from './chunk-RILUG7JB.js';
5
+ import { AXIS } from './chunk-DI2FBGKM.js';
6
6
  import { TooltipCard } from './chunk-VIOSQN4Z.js';
7
7
  import { seriesKey, hasNoData } from './chunk-UJIV5PVI.js';
8
- import { ChartEmpty, frameProps } from './chunk-3N43QT36.js';
8
+ import { ChartEmpty, frameProps } from './chunk-56WD3OHA.js';
9
9
  import { BORDER, seriesColor, MUTED, PANEL, TEXT } from './chunk-UATB2IRY.js';
10
10
  import { useState, useMemo } from 'react';
11
11
  import { LineChart, XAxis, YAxis, Tooltip, Line } from 'recharts';
@@ -1,11 +1,11 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var chunkTPH5T3DA_cjs = require('./chunk-TPH5T3DA.cjs');
4
+ var chunkZWHCUYIN_cjs = require('./chunk-ZWHCUYIN.cjs');
5
5
  require('./chunk-DBZQI4HM.cjs');
6
- var chunkRLHGPHC7_cjs = require('./chunk-RLHGPHC7.cjs');
6
+ var chunkG4WOPX4D_cjs = require('./chunk-G4WOPX4D.cjs');
7
7
  require('./chunk-T3K6Q34U.cjs');
8
- var chunk6NRRABPF_cjs = require('./chunk-6NRRABPF.cjs');
8
+ var chunkSR2ESX3R_cjs = require('./chunk-SR2ESX3R.cjs');
9
9
  var chunkLT3UC65O_cjs = require('./chunk-LT3UC65O.cjs');
10
10
  var jsxRuntime = require('react/jsx-runtime');
11
11
 
@@ -96,7 +96,7 @@ var CalendarChart = ({
96
96
  const name = ariaLabel ?? "Calendar chart";
97
97
  const days = collectDays(data);
98
98
  if (!days) {
99
- return /* @__PURE__ */ jsxRuntime.jsx(chunk6NRRABPF_cjs.ChartEmpty, { message: emptyMessage, ariaLabel: name, height: EMPTY_HEIGHT, width });
99
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkSR2ESX3R_cjs.ChartEmpty, { message: emptyMessage, ariaLabel: name, height: EMPTY_HEIGHT, width });
100
100
  }
101
101
  const given = {
102
102
  from: from === void 0 ? void 0 : parseDay(from),
@@ -107,7 +107,7 @@ var CalendarChart = ({
107
107
  const end = given.to ?? (calendar ? dayOf(partsOf(days.last).year, 11, 31) : days.last);
108
108
  const blocks = calendar ? yearSpans(start, end) : end >= start ? [{ year: void 0, from: start, to: end }] : [];
109
109
  if (blocks.length === 0) {
110
- return /* @__PURE__ */ jsxRuntime.jsx(chunk6NRRABPF_cjs.ChartEmpty, { message: emptyMessage, ariaLabel: name, height: EMPTY_HEIGHT, width });
110
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkSR2ESX3R_cjs.ChartEmpty, { message: emptyMessage, ariaLabel: name, height: EMPTY_HEIGHT, width });
111
111
  }
112
112
  const month = new Intl.DateTimeFormat(locale, { month: "short", timeZone: "UTC" });
113
113
  const date = new Intl.DateTimeFormat(locale, { dateStyle: "full", timeZone: "UTC" });
@@ -145,6 +145,8 @@ var CalendarChart = ({
145
145
  {
146
146
  className: chunkLT3UC65O_cjs.CALENDAR_DARK_CLASS,
147
147
  style: {
148
+ // Time keeps its order under `dir="rtl"`, as a chart's axis does.
149
+ direction: "ltr",
148
150
  display: "flex",
149
151
  flexDirection: "column",
150
152
  gap: "0.75rem",
@@ -152,14 +154,14 @@ var CalendarChart = ({
152
154
  width: width ?? "fit-content",
153
155
  maxWidth: "100%",
154
156
  minWidth: 0,
155
- fontSize: chunkRLHGPHC7_cjs.TEXT_SIZE,
157
+ fontSize: chunkG4WOPX4D_cjs.TEXT_SIZE,
156
158
  color: chunkLT3UC65O_cjs.MUTED
157
159
  },
158
160
  children: [
159
161
  grids.map(({ block, metrics: m, columns, cells, label }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-calendar-block": "", style: { minWidth: 0 }, children: [
160
162
  blocks.length > 1 && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: "0 0 0.25rem", fontWeight: 600, color: chunkLT3UC65O_cjs.TEXT }, children: block.year }),
161
163
  /* @__PURE__ */ jsxRuntime.jsx(
162
- chunkTPH5T3DA_cjs.HeatGrid,
164
+ chunkZWHCUYIN_cjs.HeatGrid,
163
165
  {
164
166
  rows,
165
167
  columns,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/calendarGrid.ts","../src/CalendarChart.tsx"],"names":["jsx","ChartEmpty","CALENDAR_STEPS","metrics","jsxs","CALENDAR_DARK_CLASS","TEXT_SIZE","MUTED","TEXT","HeatGrid"],"mappings":"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","file":"CalendarChart.cjs","sourcesContent":["// The date maths of `CalendarChart`. A day is a whole number: the days since\n// 1970-01-01 in UTC, so nothing here reads the time zone of the machine or the\n// date of today.\n\nexport const DAY_MS = 86_400_000;\n\n/** The weekday a week starts on: 0 is Sunday, 1 is Monday. */\nexport type WeekStart = 0 | 1;\n\nconst mod = (n: number, by: number) => ((n % by) + by) % by;\n\n/** The day number of an ISO date (`2026-03-14`), or `undefined` when it is not a real date. */\nexport const parseDay = (iso: string): number | undefined => {\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(iso);\n if (!match) return undefined;\n const [year, month, date] = [Number(match[1]), Number(match[2]), Number(match[3])];\n const time = Date.UTC(year, month - 1, date);\n const check = new Date(time);\n // `Date.UTC` rolls 02-30 over to 03-02: a date that moved is not a date.\n return check.getUTCFullYear() === year &&\n check.getUTCMonth() === month - 1 &&\n check.getUTCDate() === date\n ? time / DAY_MS\n : undefined;\n};\n\n/** The day number of a date: `month` is 0 to 11. */\nexport const dayOf = (year: number, month: number, date: number): number =>\n Date.UTC(year, month, date) / DAY_MS;\n\n/** The ISO date of a day number. */\nexport const formatDay = (day: number): string => new Date(day * DAY_MS).toISOString().slice(0, 10);\n\n/** The weekday of a day number, 0 (Sunday) to 6. 1970-01-01 was a Thursday. */\nexport const weekdayOf = (day: number): number => mod(day + 4, 7);\n\n/** The year, month (0 to 11) and day of the month of a day number. */\nexport const partsOf = (day: number) => {\n const date = new Date(day * DAY_MS);\n return { year: date.getUTCFullYear(), month: date.getUTCMonth(), date: date.getUTCDate() };\n};\n\n/** The row of a day in a week that starts on `weekStart`: 0 for the first day of the week. */\nexport const rowOf = (day: number, weekStart: WeekStart): number =>\n mod(weekdayOf(day) - weekStart, 7);\n\nexport type GridDay = { day: number; row: number; column: number };\n\nexport type WeekGrid = {\n /** The first day of the first column: on or before `from`. */\n start: number;\n /** The number of columns. 0 when the range is empty. */\n weeks: number;\n /** Every day of the range, in order. The slots before `from` and after `to` have no day. */\n days: GridDay[];\n};\n\n/** The days from `from` to `to` (inclusive) laid out as weeks in columns and weekdays in rows. */\nexport const weekGrid = (from: number, to: number, weekStart: WeekStart): WeekGrid => {\n if (to < from) return { start: from, weeks: 0, days: [] };\n const start = from - rowOf(from, weekStart);\n const days = Array.from({ length: to - from + 1 }, (_, i): GridDay => {\n const day = from + i;\n return { day, row: rowOf(day, weekStart), column: Math.floor((day - start) / 7) };\n });\n return { start, weeks: Math.floor((to - start) / 7) + 1, days };\n};\n\nexport type YearSpan = { year: number; from: number; to: number };\n\n/** `from` to `to` cut at the turn of each year: one block of the `calendar` layout per span. */\nexport const yearSpans = (from: number, to: number): YearSpan[] => {\n const spans: YearSpan[] = [];\n if (to < from) return spans;\n for (let year = partsOf(from).year; year <= partsOf(to).year; year++) {\n spans.push({\n year,\n from: Math.max(from, dayOf(year, 0, 1)),\n to: Math.min(to, dayOf(year, 11, 31)),\n });\n }\n return spans;\n};\n\nexport type MonthMark = { column: number; month: number };\n\n// Room a month name needs, in columns: two months closer than this would\n// print over each other.\nconst MIN_MARK_GAP = 3;\n\n/**\n * Where the month names go: above the first full week of each month, that is\n * the first column whose first day falls in the first seven days of the\n * month. A range that starts in the middle of a month also names that month\n * above its first column, unless the next name is too close to leave room.\n */\nexport const monthMarks = (grid: WeekGrid): MonthMark[] => {\n if (grid.weeks === 0) return [];\n const marks: MonthMark[] = [];\n for (let column = 0; column < grid.weeks; column++) {\n const { month, date } = partsOf(grid.start + column * 7);\n if (date <= 7) marks.push({ column, month });\n }\n const first = grid.days[0];\n const leading = partsOf(first.day).month;\n const next = marks[0];\n if (!next || (next.month !== leading && next.column >= MIN_MARK_GAP)) {\n marks.unshift({ column: 0, month: leading });\n }\n return marks;\n};\n\n/** The 0-based step a value takes on the scale: 0 is empty, 1 to `steps` split `(0, max]` evenly. */\nexport const stepOf = (value: number, max: number, steps = 4): number =>\n !(value > 0) || !(max > 0) ? 0 : Math.min(steps, Math.max(1, Math.ceil((value / max) * steps)));\n\n/** How big the cells are: a short range gets larger ones, a long one fits more weeks on screen. */\nexport const cellMetrics = (weeks: number) =>\n weeks <= 26 ? { size: 18, gap: 4, radius: 4 } : { size: 12, gap: 3, radius: 3 };\n\nexport type DayValues = {\n /** The summed value of each valid day. */\n values: Map<number, number>;\n first: number;\n last: number;\n};\n\n/** The valid days of `data` by day number, a day listed twice summed. `undefined` when none is valid. */\nexport const collectDays = (\n data: readonly { day: string; value: number }[]\n): DayValues | undefined => {\n const values = new Map<number, number>();\n for (const { day, value } of data) {\n const n = parseDay(day);\n if (n === undefined || !Number.isFinite(value)) continue;\n values.set(n, (values.get(n) ?? 0) + value);\n }\n if (values.size === 0) return undefined;\n const days = [...values.keys()];\n return { values, first: Math.min(...days), last: Math.max(...days) };\n};\n","import { TEXT_SIZE } from './core/axes';\nimport { CALENDAR_DARK_CLASS, CALENDAR_STEPS, MUTED, TEXT } from './core/colors';\nimport { ChartEmpty } from './core/frame';\nimport { HeatGrid, type HeatCell } from './core/HeatGrid';\nimport {\n cellMetrics,\n collectDays,\n DAY_MS,\n dayOf,\n monthMarks,\n parseDay,\n partsOf,\n stepOf,\n weekGrid,\n yearSpans,\n type WeekStart,\n} from './calendarGrid';\nimport type { ChartEmptyProps, ChartProps } from './types';\n\nexport type CalendarDay = {\n /** The date, `YYYY-MM-DD`. A day listed twice adds up; anything else is ignored. */\n day: string;\n value: number;\n};\n\nexport type CalendarChartProps = Omit<ChartProps, 'children' | 'height'> &\n ChartEmptyProps & {\n data: CalendarDay[];\n /**\n * First day shown, `YYYY-MM-DD`. Default: the first day of the earliest\n * year of `data` in the `calendar` layout, the earliest day in `range`.\n */\n from?: string;\n /** Last day shown, `YYYY-MM-DD`. Default: the end of the latest year, or the latest day in `range`. */\n to?: string;\n /**\n * `calendar` draws one block per year, with the months named above their\n * first full week. `range` draws one continuous grid from `from` to `to`,\n * with larger cells when the range is short. Default `calendar`.\n */\n layout?: 'calendar' | 'range';\n /** The weekday a week starts on: 1 for Monday (default), 0 for Sunday. */\n weekStart?: WeekStart;\n /** Format the value in the tooltip and in the name of each day. */\n formatValue?: (value: number) => string;\n /** Text at the low end of the scale under the grid. Default `Less`. */\n lessLabel?: string;\n /** Text at the high end of the scale under the grid. Default `More`. */\n moreLabel?: string;\n /** The language of the month, weekday and date names (BCP 47). Default `en-US`. */\n locale?: string;\n };\n\n// Height of the empty state, which has no grid to take one from.\nconst EMPTY_HEIGHT = 120;\n\n// Tuesday, Thursday and the weekend carry no name: a name every second row\n// leaves each one room.\nconst NAMED_WEEKDAYS = [1, 3, 5];\n\ntype Block = { year: number | undefined; from: number; to: number };\n\nexport const CalendarChart = ({\n data,\n from,\n to,\n layout = 'calendar',\n weekStart = 1,\n formatValue = String,\n locale = 'en-US',\n lessLabel = 'Less',\n moreLabel = 'More',\n emptyMessage = 'No data',\n ariaLabel,\n width,\n}: CalendarChartProps) => {\n const name = ariaLabel ?? 'Calendar chart';\n const days = collectDays(data);\n if (!days) {\n return (\n <ChartEmpty message={emptyMessage} ariaLabel={name} height={EMPTY_HEIGHT} width={width} />\n );\n }\n const given = {\n from: from === undefined ? undefined : parseDay(from),\n to: to === undefined ? undefined : parseDay(to),\n };\n const calendar = layout === 'calendar';\n const start = given.from ?? (calendar ? dayOf(partsOf(days.first).year, 0, 1) : days.first);\n const end = given.to ?? (calendar ? dayOf(partsOf(days.last).year, 11, 31) : days.last);\n const blocks: Block[] = calendar\n ? yearSpans(start, end)\n : end >= start\n ? [{ year: undefined, from: start, to: end }]\n : [];\n if (blocks.length === 0) {\n return (\n <ChartEmpty message={emptyMessage} ariaLabel={name} height={EMPTY_HEIGHT} width={width} />\n );\n }\n\n const month = new Intl.DateTimeFormat(locale, { month: 'short', timeZone: 'UTC' });\n const date = new Intl.DateTimeFormat(locale, { dateStyle: 'full', timeZone: 'UTC' });\n const weekday = new Intl.DateTimeFormat(locale, { weekday: 'short', timeZone: 'UTC' });\n const monthName = (m: number) => month.format(Date.UTC(2024, m, 1));\n // 2024-01-07 was a Sunday.\n const weekdayName = (d: number) => weekday.format(Date.UTC(2024, 0, 7 + d));\n const rows = Array.from({ length: 7 }, (_, row) => {\n const d = (row + weekStart) % 7;\n return NAMED_WEEKDAYS.includes(d) ? weekdayName(d) : '';\n });\n\n // One scale for every block, so two years compare.\n const max = Math.max(0, ...days.values.values());\n const color = (value: number) => CALENDAR_STEPS[stepOf(value, max)];\n\n const grids = blocks.map((block) => {\n const grid = weekGrid(block.from, block.to, weekStart);\n const metrics = cellMetrics(grid.weeks);\n const columns = Array.from({ length: grid.weeks }, () => '');\n for (const mark of monthMarks(grid)) columns[mark.column] = monthName(mark.month);\n const cells = grid.days.map((d): HeatCell => {\n const value = days.values.get(d.day) ?? 0;\n return {\n row: d.row,\n column: d.column,\n color: color(value),\n title: date.format(d.day * DAY_MS),\n label: '',\n value: formatValue(value),\n };\n });\n const label = block.year !== undefined && blocks.length > 1 ? `${name}, ${block.year}` : name;\n return { block, grid, metrics, columns, cells, label };\n });\n\n const metrics = grids[0].metrics;\n return (\n <div\n className={CALENDAR_DARK_CLASS}\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: '0.75rem',\n // As wide as the grid, so the scale lines up with its right edge.\n width: width ?? 'fit-content',\n maxWidth: '100%',\n minWidth: 0,\n fontSize: TEXT_SIZE,\n color: MUTED,\n }}\n >\n {grids.map(({ block, metrics: m, columns, cells, label }) => (\n <div key={block.year ?? 'range'} data-calendar-block=\"\" style={{ minWidth: 0 }}>\n {blocks.length > 1 && (\n <p style={{ margin: '0 0 0.25rem', fontWeight: 600, color: TEXT }}>{block.year}</p>\n )}\n <HeatGrid\n rows={rows}\n columns={columns}\n cells={cells}\n cellHeight={m.size}\n columnWidth={m.size}\n gap={m.gap}\n cellRadius={m.radius}\n labelsAbove\n thinLabels={false}\n ariaLabel={label}\n />\n </div>\n ))}\n <div\n data-calendar-legend=\"\"\n aria-hidden\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'flex-end',\n // The grid sits in a box padded by 3px, room for its focus rings.\n paddingRight: 3,\n gap: metrics.gap,\n }}\n >\n <span style={{ marginRight: 4 }}>{lessLabel}</span>\n {CALENDAR_STEPS.map((step, i) => (\n <span\n key={i}\n data-calendar-step=\"\"\n style={{\n width: metrics.size,\n height: metrics.size,\n borderRadius: metrics.radius,\n background: step,\n }}\n />\n ))}\n <span style={{ marginLeft: 4 }}>{moreLabel}</span>\n </div>\n </div>\n );\n};\n"]}
1
+ {"version":3,"sources":["../src/calendarGrid.ts","../src/CalendarChart.tsx"],"names":["jsx","ChartEmpty","CALENDAR_STEPS","metrics","jsxs","CALENDAR_DARK_CLASS","TEXT_SIZE","MUTED","TEXT","HeatGrid"],"mappings":"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","file":"CalendarChart.cjs","sourcesContent":["// The date maths of `CalendarChart`. A day is a whole number: the days since\n// 1970-01-01 in UTC, so nothing here reads the time zone of the machine or the\n// date of today.\n\nexport const DAY_MS = 86_400_000;\n\n/** The weekday a week starts on: 0 is Sunday, 1 is Monday. */\nexport type WeekStart = 0 | 1;\n\nconst mod = (n: number, by: number) => ((n % by) + by) % by;\n\n/** The day number of an ISO date (`2026-03-14`), or `undefined` when it is not a real date. */\nexport const parseDay = (iso: string): number | undefined => {\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(iso);\n if (!match) return undefined;\n const [year, month, date] = [Number(match[1]), Number(match[2]), Number(match[3])];\n const time = Date.UTC(year, month - 1, date);\n const check = new Date(time);\n // `Date.UTC` rolls 02-30 over to 03-02: a date that moved is not a date.\n return check.getUTCFullYear() === year &&\n check.getUTCMonth() === month - 1 &&\n check.getUTCDate() === date\n ? time / DAY_MS\n : undefined;\n};\n\n/** The day number of a date: `month` is 0 to 11. */\nexport const dayOf = (year: number, month: number, date: number): number =>\n Date.UTC(year, month, date) / DAY_MS;\n\n/** The ISO date of a day number. */\nexport const formatDay = (day: number): string => new Date(day * DAY_MS).toISOString().slice(0, 10);\n\n/** The weekday of a day number, 0 (Sunday) to 6. 1970-01-01 was a Thursday. */\nexport const weekdayOf = (day: number): number => mod(day + 4, 7);\n\n/** The year, month (0 to 11) and day of the month of a day number. */\nexport const partsOf = (day: number) => {\n const date = new Date(day * DAY_MS);\n return { year: date.getUTCFullYear(), month: date.getUTCMonth(), date: date.getUTCDate() };\n};\n\n/** The row of a day in a week that starts on `weekStart`: 0 for the first day of the week. */\nexport const rowOf = (day: number, weekStart: WeekStart): number =>\n mod(weekdayOf(day) - weekStart, 7);\n\nexport type GridDay = { day: number; row: number; column: number };\n\nexport type WeekGrid = {\n /** The first day of the first column: on or before `from`. */\n start: number;\n /** The number of columns. 0 when the range is empty. */\n weeks: number;\n /** Every day of the range, in order. The slots before `from` and after `to` have no day. */\n days: GridDay[];\n};\n\n/** The days from `from` to `to` (inclusive) laid out as weeks in columns and weekdays in rows. */\nexport const weekGrid = (from: number, to: number, weekStart: WeekStart): WeekGrid => {\n if (to < from) return { start: from, weeks: 0, days: [] };\n const start = from - rowOf(from, weekStart);\n const days = Array.from({ length: to - from + 1 }, (_, i): GridDay => {\n const day = from + i;\n return { day, row: rowOf(day, weekStart), column: Math.floor((day - start) / 7) };\n });\n return { start, weeks: Math.floor((to - start) / 7) + 1, days };\n};\n\nexport type YearSpan = { year: number; from: number; to: number };\n\n/** `from` to `to` cut at the turn of each year: one block of the `calendar` layout per span. */\nexport const yearSpans = (from: number, to: number): YearSpan[] => {\n const spans: YearSpan[] = [];\n if (to < from) return spans;\n for (let year = partsOf(from).year; year <= partsOf(to).year; year++) {\n spans.push({\n year,\n from: Math.max(from, dayOf(year, 0, 1)),\n to: Math.min(to, dayOf(year, 11, 31)),\n });\n }\n return spans;\n};\n\nexport type MonthMark = { column: number; month: number };\n\n// Room a month name needs, in columns: two months closer than this would\n// print over each other.\nconst MIN_MARK_GAP = 3;\n\n/**\n * Where the month names go: above the first full week of each month, that is\n * the first column whose first day falls in the first seven days of the\n * month. A range that starts in the middle of a month also names that month\n * above its first column, unless the next name is too close to leave room.\n */\nexport const monthMarks = (grid: WeekGrid): MonthMark[] => {\n if (grid.weeks === 0) return [];\n const marks: MonthMark[] = [];\n for (let column = 0; column < grid.weeks; column++) {\n const { month, date } = partsOf(grid.start + column * 7);\n if (date <= 7) marks.push({ column, month });\n }\n const first = grid.days[0];\n const leading = partsOf(first.day).month;\n const next = marks[0];\n if (!next || (next.month !== leading && next.column >= MIN_MARK_GAP)) {\n marks.unshift({ column: 0, month: leading });\n }\n return marks;\n};\n\n/** The 0-based step a value takes on the scale: 0 is empty, 1 to `steps` split `(0, max]` evenly. */\nexport const stepOf = (value: number, max: number, steps = 4): number =>\n !(value > 0) || !(max > 0) ? 0 : Math.min(steps, Math.max(1, Math.ceil((value / max) * steps)));\n\n/** How big the cells are: a short range gets larger ones, a long one fits more weeks on screen. */\nexport const cellMetrics = (weeks: number) =>\n weeks <= 26 ? { size: 18, gap: 4, radius: 4 } : { size: 12, gap: 3, radius: 3 };\n\nexport type DayValues = {\n /** The summed value of each valid day. */\n values: Map<number, number>;\n first: number;\n last: number;\n};\n\n/** The valid days of `data` by day number, a day listed twice summed. `undefined` when none is valid. */\nexport const collectDays = (\n data: readonly { day: string; value: number }[]\n): DayValues | undefined => {\n const values = new Map<number, number>();\n for (const { day, value } of data) {\n const n = parseDay(day);\n if (n === undefined || !Number.isFinite(value)) continue;\n values.set(n, (values.get(n) ?? 0) + value);\n }\n if (values.size === 0) return undefined;\n const days = [...values.keys()];\n return { values, first: Math.min(...days), last: Math.max(...days) };\n};\n","import { TEXT_SIZE } from './core/axes';\nimport { CALENDAR_DARK_CLASS, CALENDAR_STEPS, MUTED, TEXT } from './core/colors';\nimport { ChartEmpty } from './core/frame';\nimport { HeatGrid, type HeatCell } from './core/HeatGrid';\nimport {\n cellMetrics,\n collectDays,\n DAY_MS,\n dayOf,\n monthMarks,\n parseDay,\n partsOf,\n stepOf,\n weekGrid,\n yearSpans,\n type WeekStart,\n} from './calendarGrid';\nimport type { ChartEmptyProps, ChartProps } from './types';\n\nexport type CalendarDay = {\n /** The date, `YYYY-MM-DD`. A day listed twice adds up; anything else is ignored. */\n day: string;\n value: number;\n};\n\nexport type CalendarChartProps = Omit<ChartProps, 'children' | 'height'> &\n ChartEmptyProps & {\n data: CalendarDay[];\n /**\n * First day shown, `YYYY-MM-DD`. Default: the first day of the earliest\n * year of `data` in the `calendar` layout, the earliest day in `range`.\n */\n from?: string;\n /** Last day shown, `YYYY-MM-DD`. Default: the end of the latest year, or the latest day in `range`. */\n to?: string;\n /**\n * `calendar` draws one block per year, with the months named above their\n * first full week. `range` draws one continuous grid from `from` to `to`,\n * with larger cells when the range is short. Default `calendar`.\n */\n layout?: 'calendar' | 'range';\n /** The weekday a week starts on: 1 for Monday (default), 0 for Sunday. */\n weekStart?: WeekStart;\n /** Format the value in the tooltip and in the name of each day. */\n formatValue?: (value: number) => string;\n /** Text at the low end of the scale under the grid. Default `Less`. */\n lessLabel?: string;\n /** Text at the high end of the scale under the grid. Default `More`. */\n moreLabel?: string;\n /** The language of the month, weekday and date names (BCP 47). Default `en-US`. */\n locale?: string;\n };\n\n// Height of the empty state, which has no grid to take one from.\nconst EMPTY_HEIGHT = 120;\n\n// Tuesday, Thursday and the weekend carry no name: a name every second row\n// leaves each one room.\nconst NAMED_WEEKDAYS = [1, 3, 5];\n\ntype Block = { year: number | undefined; from: number; to: number };\n\nexport const CalendarChart = ({\n data,\n from,\n to,\n layout = 'calendar',\n weekStart = 1,\n formatValue = String,\n locale = 'en-US',\n lessLabel = 'Less',\n moreLabel = 'More',\n emptyMessage = 'No data',\n ariaLabel,\n width,\n}: CalendarChartProps) => {\n const name = ariaLabel ?? 'Calendar chart';\n const days = collectDays(data);\n if (!days) {\n return (\n <ChartEmpty message={emptyMessage} ariaLabel={name} height={EMPTY_HEIGHT} width={width} />\n );\n }\n const given = {\n from: from === undefined ? undefined : parseDay(from),\n to: to === undefined ? undefined : parseDay(to),\n };\n const calendar = layout === 'calendar';\n const start = given.from ?? (calendar ? dayOf(partsOf(days.first).year, 0, 1) : days.first);\n const end = given.to ?? (calendar ? dayOf(partsOf(days.last).year, 11, 31) : days.last);\n const blocks: Block[] = calendar\n ? yearSpans(start, end)\n : end >= start\n ? [{ year: undefined, from: start, to: end }]\n : [];\n if (blocks.length === 0) {\n return (\n <ChartEmpty message={emptyMessage} ariaLabel={name} height={EMPTY_HEIGHT} width={width} />\n );\n }\n\n const month = new Intl.DateTimeFormat(locale, { month: 'short', timeZone: 'UTC' });\n const date = new Intl.DateTimeFormat(locale, { dateStyle: 'full', timeZone: 'UTC' });\n const weekday = new Intl.DateTimeFormat(locale, { weekday: 'short', timeZone: 'UTC' });\n const monthName = (m: number) => month.format(Date.UTC(2024, m, 1));\n // 2024-01-07 was a Sunday.\n const weekdayName = (d: number) => weekday.format(Date.UTC(2024, 0, 7 + d));\n const rows = Array.from({ length: 7 }, (_, row) => {\n const d = (row + weekStart) % 7;\n return NAMED_WEEKDAYS.includes(d) ? weekdayName(d) : '';\n });\n\n // One scale for every block, so two years compare.\n const max = Math.max(0, ...days.values.values());\n const color = (value: number) => CALENDAR_STEPS[stepOf(value, max)];\n\n const grids = blocks.map((block) => {\n const grid = weekGrid(block.from, block.to, weekStart);\n const metrics = cellMetrics(grid.weeks);\n const columns = Array.from({ length: grid.weeks }, () => '');\n for (const mark of monthMarks(grid)) columns[mark.column] = monthName(mark.month);\n const cells = grid.days.map((d): HeatCell => {\n const value = days.values.get(d.day) ?? 0;\n return {\n row: d.row,\n column: d.column,\n color: color(value),\n title: date.format(d.day * DAY_MS),\n label: '',\n value: formatValue(value),\n };\n });\n const label = block.year !== undefined && blocks.length > 1 ? `${name}, ${block.year}` : name;\n return { block, grid, metrics, columns, cells, label };\n });\n\n const metrics = grids[0].metrics;\n return (\n <div\n className={CALENDAR_DARK_CLASS}\n style={{\n // Time keeps its order under `dir=\"rtl\"`, as a chart's axis does.\n direction: 'ltr',\n display: 'flex',\n flexDirection: 'column',\n gap: '0.75rem',\n // As wide as the grid, so the scale lines up with its right edge.\n width: width ?? 'fit-content',\n maxWidth: '100%',\n minWidth: 0,\n fontSize: TEXT_SIZE,\n color: MUTED,\n }}\n >\n {grids.map(({ block, metrics: m, columns, cells, label }) => (\n <div key={block.year ?? 'range'} data-calendar-block=\"\" style={{ minWidth: 0 }}>\n {blocks.length > 1 && (\n <p style={{ margin: '0 0 0.25rem', fontWeight: 600, color: TEXT }}>{block.year}</p>\n )}\n <HeatGrid\n rows={rows}\n columns={columns}\n cells={cells}\n cellHeight={m.size}\n columnWidth={m.size}\n gap={m.gap}\n cellRadius={m.radius}\n labelsAbove\n thinLabels={false}\n ariaLabel={label}\n />\n </div>\n ))}\n <div\n data-calendar-legend=\"\"\n aria-hidden\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'flex-end',\n // The grid sits in a box padded by 3px, room for its focus rings.\n paddingRight: 3,\n gap: metrics.gap,\n }}\n >\n <span style={{ marginRight: 4 }}>{lessLabel}</span>\n {CALENDAR_STEPS.map((step, i) => (\n <span\n key={i}\n data-calendar-step=\"\"\n style={{\n width: metrics.size,\n height: metrics.size,\n borderRadius: metrics.radius,\n background: step,\n }}\n />\n ))}\n <span style={{ marginLeft: 4 }}>{moreLabel}</span>\n </div>\n </div>\n );\n};\n"]}
@@ -1,9 +1,9 @@
1
1
  "use client";
2
- import { HeatGrid } from './chunk-ICL5K2CW.js';
2
+ import { HeatGrid } from './chunk-UL3SNXQR.js';
3
3
  import './chunk-BFEDLXVW.js';
4
- import { TEXT_SIZE } from './chunk-RILUG7JB.js';
4
+ import { TEXT_SIZE } from './chunk-DI2FBGKM.js';
5
5
  import './chunk-VIOSQN4Z.js';
6
- import { ChartEmpty } from './chunk-3N43QT36.js';
6
+ import { ChartEmpty } from './chunk-56WD3OHA.js';
7
7
  import { MUTED, CALENDAR_DARK_CLASS, TEXT, CALENDAR_STEPS } from './chunk-UATB2IRY.js';
8
8
  import { jsx, jsxs } from 'react/jsx-runtime';
9
9
 
@@ -143,6 +143,8 @@ var CalendarChart = ({
143
143
  {
144
144
  className: CALENDAR_DARK_CLASS,
145
145
  style: {
146
+ // Time keeps its order under `dir="rtl"`, as a chart's axis does.
147
+ direction: "ltr",
146
148
  display: "flex",
147
149
  flexDirection: "column",
148
150
  gap: "0.75rem",