@kind-ui/charts 0.1.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 (121) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/LICENSE +21 -0
  3. package/README.md +966 -0
  4. package/dist/activity-rings.d.ts +47 -0
  5. package/dist/activity-rings.js +55 -0
  6. package/dist/animation.d.ts +27 -0
  7. package/dist/animation.js +102 -0
  8. package/dist/area-chart.d.ts +9 -0
  9. package/dist/area-chart.js +33 -0
  10. package/dist/area-clay.d.ts +2 -0
  11. package/dist/area-clay.js +6 -0
  12. package/dist/area-material.d.ts +8 -0
  13. package/dist/area-material.js +66 -0
  14. package/dist/area-series.d.ts +11 -0
  15. package/dist/area-series.js +34 -0
  16. package/dist/bar-category.d.ts +5 -0
  17. package/dist/bar-category.js +35 -0
  18. package/dist/bar-chart.d.ts +17 -0
  19. package/dist/bar-chart.js +42 -0
  20. package/dist/bar-clay.d.ts +4 -0
  21. package/dist/bar-clay.js +6 -0
  22. package/dist/bar-material.d.ts +8 -0
  23. package/dist/bar-material.js +19 -0
  24. package/dist/bar-paper.d.ts +2 -0
  25. package/dist/bar-paper.js +6 -0
  26. package/dist/bar-series.d.ts +13 -0
  27. package/dist/bar-series.js +178 -0
  28. package/dist/box-material.d.ts +14 -0
  29. package/dist/box-material.js +30 -0
  30. package/dist/box-plot.d.ts +50 -0
  31. package/dist/box-plot.js +218 -0
  32. package/dist/category-cells.d.ts +6 -0
  33. package/dist/category-cells.js +41 -0
  34. package/dist/chart-context.d.ts +11 -0
  35. package/dist/chart-context.js +9 -0
  36. package/dist/combo-chart.d.ts +16 -0
  37. package/dist/combo-chart.js +64 -0
  38. package/dist/configured-line-chart.d.ts +79 -0
  39. package/dist/configured-line-chart.js +77 -0
  40. package/dist/emphasis.d.ts +44 -0
  41. package/dist/emphasis.js +128 -0
  42. package/dist/heatmap-model.d.ts +38 -0
  43. package/dist/heatmap-model.js +73 -0
  44. package/dist/heatmap.d.ts +56 -0
  45. package/dist/heatmap.js +366 -0
  46. package/dist/histogram-chart.d.ts +14 -0
  47. package/dist/histogram-chart.js +27 -0
  48. package/dist/histogram-data.d.ts +17 -0
  49. package/dist/histogram-data.js +66 -0
  50. package/dist/histogram-material.d.ts +13 -0
  51. package/dist/histogram-material.js +8 -0
  52. package/dist/histogram-series.d.ts +16 -0
  53. package/dist/histogram-series.js +67 -0
  54. package/dist/index.d.ts +45 -0
  55. package/dist/index.js +36 -0
  56. package/dist/legend.d.ts +16 -0
  57. package/dist/legend.js +30 -0
  58. package/dist/line-chart.d.ts +41 -0
  59. package/dist/line-chart.js +160 -0
  60. package/dist/line-material.d.ts +9 -0
  61. package/dist/line-material.js +24 -0
  62. package/dist/line-series.d.ts +15 -0
  63. package/dist/line-series.js +40 -0
  64. package/dist/pie-chart.d.ts +17 -0
  65. package/dist/pie-chart.js +68 -0
  66. package/dist/pie-material.d.ts +19 -0
  67. package/dist/pie-material.js +16 -0
  68. package/dist/pie-series.d.ts +14 -0
  69. package/dist/pie-series.js +208 -0
  70. package/dist/polar-chart.d.ts +33 -0
  71. package/dist/polar-chart.js +145 -0
  72. package/dist/polar-material.d.ts +7 -0
  73. package/dist/polar-material.js +9 -0
  74. package/dist/polar-series.d.ts +17 -0
  75. package/dist/polar-series.js +169 -0
  76. package/dist/radar-interaction.d.ts +29 -0
  77. package/dist/radar-interaction.js +138 -0
  78. package/dist/radial-bar-label.d.ts +15 -0
  79. package/dist/radial-bar-label.js +136 -0
  80. package/dist/radial-category.d.ts +4 -0
  81. package/dist/radial-category.js +4 -0
  82. package/dist/root.d.ts +14 -0
  83. package/dist/root.js +29 -0
  84. package/dist/sankey-chart.d.ts +33 -0
  85. package/dist/sankey-chart.js +142 -0
  86. package/dist/sankey-colors.d.ts +10 -0
  87. package/dist/sankey-colors.js +6 -0
  88. package/dist/sankey-data.d.ts +30 -0
  89. package/dist/sankey-data.js +65 -0
  90. package/dist/sankey-finish.d.ts +13 -0
  91. package/dist/sankey-finish.js +10 -0
  92. package/dist/sankey-legend.d.ts +14 -0
  93. package/dist/sankey-legend.js +9 -0
  94. package/dist/sankey-marks.d.ts +31 -0
  95. package/dist/sankey-marks.js +67 -0
  96. package/dist/sankey-table.d.ts +11 -0
  97. package/dist/sankey-table.js +8 -0
  98. package/dist/scatter-chart.d.ts +16 -0
  99. package/dist/scatter-chart.js +64 -0
  100. package/dist/scatter-material.d.ts +8 -0
  101. package/dist/scatter-material.js +39 -0
  102. package/dist/scatter-series.d.ts +11 -0
  103. package/dist/scatter-series.js +74 -0
  104. package/dist/scatter-tooltip.d.ts +24 -0
  105. package/dist/scatter-tooltip.js +96 -0
  106. package/dist/styles.css +443 -0
  107. package/dist/surface-material.d.ts +13 -0
  108. package/dist/surface-material.js +7 -0
  109. package/dist/tooltip-content.d.ts +19 -0
  110. package/dist/tooltip-content.js +60 -0
  111. package/dist/tooltip-number.d.ts +4 -0
  112. package/dist/tooltip-number.js +68 -0
  113. package/dist/tooltip.d.ts +29 -0
  114. package/dist/tooltip.js +73 -0
  115. package/dist/types.d.ts +11 -0
  116. package/dist/types.js +1 -0
  117. package/dist/waterfall-data.d.ts +24 -0
  118. package/dist/waterfall-data.js +45 -0
  119. package/dist/waterfall-series.d.ts +15 -0
  120. package/dist/waterfall-series.js +35 -0
  121. package/package.json +49 -0
@@ -0,0 +1,443 @@
1
+ @layer kind-ui {
2
+ :where(.kind-ui-configured-line-root) {
3
+ font-family: var(--kind-ui-chart-font, ui-sans-serif, system-ui, sans-serif);
4
+ }
5
+
6
+ :where(.kind-ui-configured-line-chart) {
7
+ width: 100%;
8
+ height: var(--kind-ui-chart-height, 280px);
9
+ min-width: 0;
10
+ }
11
+
12
+ :where([data-kind-ui="chart-instructions"]) {
13
+ position: absolute;
14
+ width: 1px;
15
+ height: 1px;
16
+ padding: 0;
17
+ margin: -1px;
18
+ overflow: hidden;
19
+ clip-path: inset(50%);
20
+ white-space: nowrap;
21
+ border: 0;
22
+ }
23
+
24
+ :where(.kind-ui-combo-chart .recharts-area, .kind-ui-combo-chart .recharts-area-dots) {
25
+ clip-path: var(--kind-ui-combo-area-clip, none);
26
+ }
27
+
28
+ :where(.kind-ui-area-chart .recharts-area, .kind-ui-area-chart .recharts-area-dots) {
29
+ clip-path: var(--kind-ui-line-clip, none);
30
+ }
31
+
32
+ :where(.kind-ui-bar-series) {
33
+ clip-path: var(--kind-ui-bar-clip, none);
34
+ }
35
+
36
+ :where(.kind-ui-line-chart .recharts-line, .kind-ui-line-chart .recharts-line-dots) {
37
+ clip-path: var(--kind-ui-line-clip, none);
38
+ }
39
+
40
+ :where([data-kind-ui="chart"]) {
41
+ width: 100%;
42
+ min-width: 0;
43
+ }
44
+
45
+ :where([data-kind-ui="chart-legend"]) {
46
+ display: flex;
47
+ flex-wrap: wrap;
48
+ gap: 8px;
49
+ list-style: none;
50
+ margin: 4px 0 8px;
51
+ padding: 0;
52
+ }
53
+
54
+ :where([data-kind-ui="chart-legend-button"]) {
55
+ display: inline-flex;
56
+ align-items: center;
57
+ gap: 6px;
58
+ border: 1px solid var(--kind-ui-chart-border, var(--border, currentColor));
59
+ border-radius: var(--kind-ui-chart-radius, var(--radius, 6px));
60
+ background: var(--kind-ui-chart-legend-background, var(--chart-legend-background, transparent));
61
+ color: inherit;
62
+ min-height: 24px;
63
+ padding: 3px 6px;
64
+ font-family: inherit;
65
+ font-size: 11px;
66
+ line-height: 16px;
67
+ cursor: pointer;
68
+ }
69
+
70
+ :where([data-kind-ui="chart-legend-item"] > span) {
71
+ display: inline-flex;
72
+ align-items: center;
73
+ gap: 4px;
74
+ padding: 2px 0;
75
+ font-size: 11px;
76
+ line-height: 16px;
77
+ }
78
+
79
+ :where([data-kind-ui="chart-legend-button"][aria-pressed="false"]) {
80
+ color: var(--kind-ui-chart-muted-foreground, var(--muted-foreground, GrayText));
81
+ text-decoration: none;
82
+ }
83
+
84
+ :where([data-kind-ui="chart-indicator"]) {
85
+ display: inline-block;
86
+ flex-shrink: 0;
87
+ width: 8px;
88
+ height: 8px;
89
+ background: var(--kind-ui-chart-indicator-color, currentColor);
90
+ }
91
+
92
+ :where(
93
+ [data-kind-ui="chart-legend-button"][aria-pressed="false"] [data-kind-ui="chart-indicator"]
94
+ ) {
95
+ background: currentColor;
96
+ }
97
+
98
+ :where([data-kind-ui="chart-indicator"][data-legend-shape]) {
99
+ width: 12px;
100
+ height: 12px;
101
+ background: none;
102
+ fill: var(--kind-ui-chart-indicator-color, currentColor);
103
+ }
104
+
105
+ :where(
106
+ [data-kind-ui="chart-legend-button"][aria-pressed="false"]
107
+ [data-kind-ui="chart-indicator"][data-legend-shape]
108
+ ) {
109
+ fill: currentColor;
110
+ }
111
+
112
+ :where([data-kind-ui="chart-tooltip"]) {
113
+ padding: 6px 8px;
114
+ background: var(--kind-ui-chart-popover, var(--popover, Canvas));
115
+ color: var(--kind-ui-chart-popover-foreground, var(--popover-foreground, CanvasText));
116
+ border: 1px solid var(--kind-ui-chart-border, var(--border, GrayText));
117
+ border-radius: var(--kind-ui-chart-radius, var(--radius, 8px));
118
+ font-size: 12px;
119
+ line-height: 16px;
120
+ }
121
+
122
+ :where([data-kind-ui="chart-tooltip-list"]) {
123
+ list-style: none;
124
+ padding: 0;
125
+ margin: 2px 0 0;
126
+ }
127
+
128
+ :where([data-kind-ui="chart-tooltip-item"]) {
129
+ display: flex;
130
+ align-items: center;
131
+ gap: 4px;
132
+ margin-top: 1px;
133
+ }
134
+
135
+ :where([data-kind-ui="chart-tooltip-item"] [data-kind-ui="chart-indicator"]) {
136
+ width: 3px;
137
+ height: 12px;
138
+ border-radius: 1px;
139
+ }
140
+
141
+ :where([data-kind-ui="chart-tooltip-item"] [data-indicator="dot"]) {
142
+ width: 8px;
143
+ height: 8px;
144
+ border-radius: 2px;
145
+ }
146
+
147
+ :where([data-kind-ui="chart-tooltip-item"] [data-indicator="dashed"]) {
148
+ background: transparent;
149
+ border-left: 2px dashed var(--kind-ui-chart-indicator-color, currentColor);
150
+ width: 0;
151
+ border-radius: 0;
152
+ }
153
+
154
+ :where([data-kind-ui="chart-icon"]) {
155
+ display: inline-flex;
156
+ flex-shrink: 0;
157
+ align-items: center;
158
+ }
159
+
160
+ :where([data-kind-ui="chart-icon"] > svg) {
161
+ width: 12px;
162
+ height: 12px;
163
+ }
164
+
165
+ :where([data-kind-ui="chart-tooltip-label"], [data-kind-ui="chart-tooltip-value"]) {
166
+ font-weight: 500;
167
+ }
168
+
169
+ :where([data-kind-ui="chart-tooltip-item"] > span:last-of-type) {
170
+ color: var(--kind-ui-chart-muted-foreground, var(--muted-foreground, inherit));
171
+ }
172
+
173
+ :where([data-kind-ui="chart-tooltip-value"]) {
174
+ margin-left: auto;
175
+ padding-left: 4px;
176
+ font-variant-numeric: tabular-nums;
177
+ }
178
+
179
+ :where([data-kind-ui="tooltip-number"]) {
180
+ display: inline-block;
181
+ position: relative;
182
+ min-width: max-content;
183
+ overflow: clip;
184
+ vertical-align: bottom;
185
+ white-space: pre;
186
+ font-variant-numeric: tabular-nums;
187
+ }
188
+
189
+ :where([data-kind-ui="tooltip-number-final"]) {
190
+ display: inline-block;
191
+ opacity: 0;
192
+ }
193
+
194
+ :where([data-kind-ui="tooltip-number-visual"]) {
195
+ position: absolute;
196
+ inset: 0;
197
+ display: flex;
198
+ align-items: center;
199
+ justify-content: flex-end;
200
+ direction: ltr;
201
+ pointer-events: none;
202
+ }
203
+
204
+ :where([data-kind-ui="tooltip-digit"]) {
205
+ position: relative;
206
+ display: inline-block;
207
+ width: 1ch;
208
+ height: 1lh;
209
+ overflow: clip;
210
+ flex-shrink: 0;
211
+ }
212
+
213
+ :where([data-kind-ui="tooltip-digit-reel"]) {
214
+ display: block;
215
+ line-height: inherit;
216
+ }
217
+
218
+ :where([data-kind-ui="tooltip-digit-reel"] > span) {
219
+ display: block;
220
+ height: 1lh;
221
+ }
222
+ }
223
+
224
+ @layer kind-ui {
225
+ [data-kind-ui="heatmap"] {
226
+ --heatmap-missing: #e5e7eb;
227
+ }
228
+ [data-kind-ui="heatmap-scroll"] {
229
+ container-type: inline-size;
230
+ overflow-x: auto;
231
+ max-width: 100%;
232
+ }
233
+ [data-kind-ui="heatmap-grid"] {
234
+ border-spacing: var(--heatmap-gap, 3px);
235
+ table-layout: fixed;
236
+ width: 100%;
237
+ min-width: calc(7rem + var(--heatmap-columns) * 3.25rem);
238
+ }
239
+ [data-kind-ui="heatmap-grid"] caption {
240
+ width: 100cqw;
241
+ max-width: 100cqw;
242
+ overflow-wrap: anywhere;
243
+ text-align: left;
244
+ font-weight: 600;
245
+ padding-bottom: 1rem;
246
+ }
247
+ [data-kind-ui="heatmap-grid"] th {
248
+ font-weight: 500;
249
+ font-size: 0.75rem;
250
+ overflow-wrap: anywhere;
251
+ padding: 0.4rem;
252
+ }
253
+ [data-kind-ui="heatmap-grid"] th:first-child {
254
+ width: 6rem;
255
+ text-align: left;
256
+ }
257
+ [data-kind-ui="heatmap-grid"] td {
258
+ overflow: hidden;
259
+ text-overflow: ellipsis;
260
+ white-space: nowrap;
261
+ height: 2.6rem;
262
+ text-align: center;
263
+ border-radius: 3px;
264
+ color: #111827;
265
+ font-variant-numeric: tabular-nums;
266
+ font-size: 0.75rem;
267
+ cursor: default;
268
+ }
269
+ [data-kind-ui="heatmap-grid"][data-cell-sizing="fixed"] {
270
+ --heatmap-row-width: 6.8rem;
271
+ width: calc(
272
+ var(--heatmap-row-width) +
273
+ var(--heatmap-gap, 3px) +
274
+ var(--heatmap-columns) *
275
+ (var(--heatmap-cell-size) + var(--heatmap-gap, 3px)) +
276
+ var(--heatmap-gap, 3px)
277
+ );
278
+ min-width: 0;
279
+ }
280
+ [data-kind-ui="heatmap-grid"][data-cell-sizing="fixed"][data-row-labels="hidden"] {
281
+ --heatmap-row-width: 0px;
282
+ }
283
+ [data-kind-ui="heatmap-grid"]:where([data-cell-sizing="fixed"]) caption {
284
+ width: auto;
285
+ }
286
+ [data-kind-ui="heatmap-grid"][data-cell-sizing="fixed"] col {
287
+ width: var(--heatmap-cell-size);
288
+ }
289
+ [data-kind-ui="heatmap-grid"][data-cell-sizing="fixed"] col[data-kind-ui="heatmap-row-column"] {
290
+ width: var(--heatmap-row-width);
291
+ }
292
+ [data-kind-ui="heatmap-grid"][data-cell-sizing="fixed"] tbody th {
293
+ padding-block: 0;
294
+ line-height: var(--heatmap-cell-size);
295
+ }
296
+ [data-kind-ui="heatmap-grid"][data-cell-sizing="fixed"] td {
297
+ box-sizing: border-box;
298
+ width: var(--heatmap-cell-size);
299
+ height: var(--heatmap-cell-size);
300
+ line-height: var(--heatmap-cell-size);
301
+ padding: 0;
302
+ }
303
+ [data-kind-ui="heatmap-grid"][data-row-labels="hidden"] th:first-child,
304
+ [data-kind-ui="heatmap-grid"][data-column-labels="hidden"] thead {
305
+ position: absolute;
306
+ width: 1px;
307
+ height: 1px;
308
+ padding: 0;
309
+ margin: -1px;
310
+ overflow: hidden;
311
+ clip-path: inset(50%);
312
+ white-space: nowrap;
313
+ }
314
+ [data-kind-ui="heatmap-grid"][data-row-labels="hidden"]:not([data-cell-sizing="fixed"]) {
315
+ min-width: calc(var(--heatmap-columns) * 3.25rem);
316
+ }
317
+ [data-kind-ui="heatmap-row-label"] {
318
+ display: block;
319
+ max-height: 1.3rem;
320
+ overflow: hidden;
321
+ text-overflow: ellipsis;
322
+ white-space: nowrap;
323
+ }
324
+ [data-kind-ui="heatmap-grid"] td:focus-visible {
325
+ outline: 3px solid var(--foreground, #172033);
326
+ outline-offset: 1px;
327
+ }
328
+ [data-kind-ui="heatmap-grid"] td[data-missing="true"] {
329
+ background-image: repeating-linear-gradient(135deg, transparent 0 5px, #17203315 5px 6px);
330
+ }
331
+ [data-kind-ui="heatmap-tooltip"] {
332
+ margin-top: 0.75rem;
333
+ padding: 0.6rem 0.8rem;
334
+ border: 1px solid var(--border, #d1d5db);
335
+ border-radius: 0.5rem;
336
+ font-size: 0.8rem;
337
+ overflow-wrap: anywhere;
338
+ }
339
+ [data-kind-ui="heatmap-tooltip"][hidden] {
340
+ display: none;
341
+ }
342
+ [data-kind-ui="heatmap-legend"] {
343
+ border: 0;
344
+ padding: 0;
345
+ margin-left: 0;
346
+ margin-right: 0;
347
+ width: 100%;
348
+ min-width: 0;
349
+ margin-top: 1rem;
350
+ font-size: 0.75rem;
351
+ max-width: 22rem;
352
+ }
353
+ [data-kind-ui="heatmap-ramp"] {
354
+ position: relative;
355
+ height: 0.65rem;
356
+ border-radius: 3px;
357
+ margin-top: 0.5rem;
358
+ }
359
+ [data-kind-ui="heatmap-ticks"] {
360
+ display: flex;
361
+ justify-content: space-between;
362
+ position: relative;
363
+ margin-top: 0.3rem;
364
+ }
365
+ [data-kind-ui="heatmap-missing-key"] {
366
+ display: inline-flex;
367
+ align-items: center;
368
+ gap: 0.4rem;
369
+ margin-top: 0.5rem;
370
+ }
371
+ [data-kind-ui="heatmap-missing-key"] i {
372
+ width: 0.85rem;
373
+ height: 0.85rem;
374
+ background:
375
+ repeating-linear-gradient(135deg, transparent 0 5px, #17203315 5px 6px),
376
+ var(--heatmap-missing);
377
+ border-radius: 2px;
378
+ }
379
+ [data-kind-ui="heatmap-data-table"] {
380
+ border-collapse: collapse;
381
+ width: 100%;
382
+ font-size: 0.8rem;
383
+ }
384
+ [data-kind-ui="heatmap-data-table"] :is(th, td) {
385
+ border: 1px solid var(--border, #d1d5db);
386
+ padding: 0.5rem;
387
+ text-align: left;
388
+ }
389
+ [data-kind-ui="heatmap-data-table"] caption {
390
+ padding: 0.75rem 0;
391
+ text-align: left;
392
+ }
393
+ }
394
+
395
+ @layer kind-ui {
396
+ [data-kind-ui="heatmap-zero-marker"] {
397
+ position: absolute;
398
+ top: -2px;
399
+ bottom: -2px;
400
+ width: 1px;
401
+ background: var(--foreground, #172033);
402
+ }
403
+ [data-kind-ui="heatmap-zero-label"] {
404
+ display: block;
405
+ margin-top: 0.25rem;
406
+ overflow-wrap: anywhere;
407
+ }
408
+ [data-kind-ui="heatmap-ticks"] > span {
409
+ max-width: 48%;
410
+ overflow-wrap: anywhere;
411
+ }
412
+ }
413
+
414
+ /* Heatmap materials are background paint, confined to an 8% perimeter.
415
+ The quantitative center and native geometry are untouched. */
416
+ @layer kind-ui {
417
+ [data-kind-ui="heatmap-grid"] td[data-material="paper"] {
418
+ background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20100%20100%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cpattern%20id%3D%22grain%22%20width%3D%226%22%20height%3D%227%22%20patternUnits%3D%22userSpaceOnUse%22%3E%3Cpath%20d%3D%22M1%201h1M4%204h1M2%206h1%22%20stroke%3D%22%23705c48%22%20stroke-opacity%3D%22.32%22%20stroke-width%3D%22.6%22%2F%3E%3C%2Fpattern%3E%3C%2Fdefs%3E%3Cpath%20d%3D%22M0%200H100V100H0Z%20M8%208V92H92V8Z%22%20fill%3D%22%23eadac0%22%20fill-opacity%3D%22.7%22%20fill-rule%3D%22evenodd%22%2F%3E%3Cpath%20d%3D%22M0%200H100V100H0Z%20M8%208V92H92V8Z%22%20fill%3D%22url%28%23grain%29%22%20fill-rule%3D%22evenodd%22%2F%3E%3Cpath%20d%3D%22M3%205L26%203L50%205L75%203L97%205L95%2030L97%2055L95%2078L97%2096L72%2095L48%2097L25%2095L3%2097L5%2074L3%2049L5%2024Z%22%20fill%3D%22none%22%20stroke%3D%22%235c4938%22%20stroke-opacity%3D%22.65%22%20stroke-width%3D%22.8%22%2F%3E%3Cpath%20d%3D%22M5%203L30%205L58%203L83%205L95%203M3%207L5%2035L3%2062L5%2090%22%20fill%3D%22none%22%20stroke%3D%22%23fffaf0%22%20stroke-opacity%3D%22.75%22%20stroke-width%3D%22.7%22%2F%3E%3C%2Fsvg%3E");
419
+ background-size: 100% 100%;
420
+ background-repeat: no-repeat;
421
+ }
422
+ [data-kind-ui="heatmap-grid"] td[data-material="clay"] {
423
+ background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20100%20100%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%22top%22%20x2%3D%220%22%20y2%3D%221%22%3E%3Cstop%20stop-color%3D%22%23fff%22%20stop-opacity%3D%22.7%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23fff%22%20stop-opacity%3D%220%22%2F%3E%3C%2FlinearGradient%3E%3ClinearGradient%20id%3D%22bottom%22%20x2%3D%220%22%20y2%3D%221%22%3E%3Cstop%20stop-color%3D%22%23172033%22%20stop-opacity%3D%220%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23172033%22%20stop-opacity%3D%22.4%22%2F%3E%3C%2FlinearGradient%3E%3ClinearGradient%20id%3D%22left%22%3E%3Cstop%20stop-color%3D%22%23fff%22%20stop-opacity%3D%22.5%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23fff%22%20stop-opacity%3D%220%22%2F%3E%3C%2FlinearGradient%3E%3ClinearGradient%20id%3D%22right%22%3E%3Cstop%20stop-color%3D%22%23172033%22%20stop-opacity%3D%220%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23172033%22%20stop-opacity%3D%22.3%22%2F%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Cpath%20d%3D%22M0%200H100V8H0Z%22%20fill%3D%22url%28%23top%29%22%2F%3E%3Cpath%20d%3D%22M0%2092H100V100H0Z%22%20fill%3D%22url%28%23bottom%29%22%2F%3E%3Cpath%20d%3D%22M0%208H8V92H0Z%22%20fill%3D%22url%28%23left%29%22%2F%3E%3Cpath%20d%3D%22M92%208H100V92H92Z%22%20fill%3D%22url%28%23right%29%22%2F%3E%3C%2Fsvg%3E");
424
+ background-size: 100% 100%;
425
+ background-repeat: no-repeat;
426
+ }
427
+ [data-kind-ui="heatmap-grid"] td[data-material="glow"] {
428
+ background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20100%20100%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%22top%22%20x2%3D%220%22%20y2%3D%221%22%3E%3Cstop%20stop-color%3D%22%23fff%22%20stop-opacity%3D%22.95%22%2F%3E%3Cstop%20offset%3D%22.2%22%20stop-color%3D%22%23fff%22%2F%3E%3Cstop%20offset%3D%22.55%22%20stop-color%3D%22%23fff%22%20stop-opacity%3D%22.35%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23fff%22%20stop-opacity%3D%220%22%2F%3E%3C%2FlinearGradient%3E%3ClinearGradient%20id%3D%22bottom%22%20x2%3D%220%22%20y2%3D%221%22%3E%3Cstop%20stop-color%3D%22%23fff%22%20stop-opacity%3D%220%22%2F%3E%3Cstop%20offset%3D%22.45%22%20stop-color%3D%22%23fff%22%20stop-opacity%3D%22.35%22%2F%3E%3Cstop%20offset%3D%22.8%22%20stop-color%3D%22%23fff%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23fff%22%20stop-opacity%3D%22.95%22%2F%3E%3C%2FlinearGradient%3E%3ClinearGradient%20id%3D%22left%22%3E%3Cstop%20stop-color%3D%22%23fff%22%20stop-opacity%3D%22.95%22%2F%3E%3Cstop%20offset%3D%22.2%22%20stop-color%3D%22%23fff%22%2F%3E%3Cstop%20offset%3D%22.55%22%20stop-color%3D%22%23fff%22%20stop-opacity%3D%22.35%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23fff%22%20stop-opacity%3D%220%22%2F%3E%3C%2FlinearGradient%3E%3ClinearGradient%20id%3D%22right%22%3E%3Cstop%20stop-color%3D%22%23fff%22%20stop-opacity%3D%220%22%2F%3E%3Cstop%20offset%3D%22.45%22%20stop-color%3D%22%23fff%22%20stop-opacity%3D%22.35%22%2F%3E%3Cstop%20offset%3D%22.8%22%20stop-color%3D%22%23fff%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23fff%22%20stop-opacity%3D%22.95%22%2F%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Cpath%20d%3D%22M0%200H100V8H0Z%22%20fill%3D%22url%28%23top%29%22%2F%3E%3Cpath%20d%3D%22M0%2092H100V100H0Z%22%20fill%3D%22url%28%23bottom%29%22%2F%3E%3Cpath%20d%3D%22M0%208H8V92H0Z%22%20fill%3D%22url%28%23left%29%22%2F%3E%3Cpath%20d%3D%22M92%208H100V92H92Z%22%20fill%3D%22url%28%23right%29%22%2F%3E%3C%2Fsvg%3E");
429
+ background-size: 100% 100%;
430
+ background-repeat: no-repeat;
431
+ }
432
+ }
433
+
434
+ @layer kind-ui {
435
+ [data-kind-ui="emphasis-paint"] {
436
+ transition: opacity 160ms cubic-bezier(0.23, 1, 0.32, 1);
437
+ }
438
+ @media (prefers-reduced-motion: reduce) {
439
+ [data-kind-ui="emphasis-paint"] {
440
+ transition: none;
441
+ }
442
+ }
443
+ }
@@ -0,0 +1,13 @@
1
+ import type { LineMaterial } from "./line-material.js";
2
+ /** Internal filled-surface finish only. Callers own native shapes, IDs and bounds. */
3
+ export declare function SurfaceMaterialFilter({ material, id, bounds, family, }: {
4
+ material: Exclude<LineMaterial, "plain">;
5
+ id: string;
6
+ bounds: {
7
+ x: number;
8
+ y: number;
9
+ width: number;
10
+ height: number;
11
+ };
12
+ family: "area" | "bar";
13
+ }): import("react").JSX.Element;
@@ -0,0 +1,7 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { AreaClayRelief } from "./area-clay.js";
4
+ /** Internal filled-surface finish only. Callers own native shapes, IDs and bounds. */
5
+ export function SurfaceMaterialFilter({ material, id, bounds, family, }) {
6
+ return (_jsx("filter", { id: id, filterUnits: "userSpaceOnUse", x: bounds.x, y: bounds.y, width: bounds.width, height: bounds.height, colorInterpolationFilters: "sRGB", children: material === "paper" ? (_jsxs(_Fragment, { children: [_jsx("feTurbulence", { type: "fractalNoise", baseFrequency: "0.65 0.3", numOctaves: 1, seed: 7, result: "fiber" }), _jsx("feFlood", { floodColor: `var(--kind-ui-${family}-paper-fiber, #fff)`, floodOpacity: `var(--kind-ui-${family}-paper-grain, 0.32)` }), _jsx("feComposite", { in2: "fiber", operator: "in", result: "texture" }), _jsx("feComposite", { in: "texture", in2: "SourceAlpha", operator: "in", result: "grain" }), _jsxs("feMerge", { children: [_jsx("feMergeNode", { in: "SourceGraphic" }), _jsx("feMergeNode", { in: "grain" })] })] })) : material === "clay" && family === "area" ? (_jsx(AreaClayRelief, {})) : material === "clay" ? (_jsxs(_Fragment, { children: [_jsx("feOffset", { in: "SourceAlpha", dx: 0, dy: 1.5, result: "lower" }), _jsx("feComposite", { in: "SourceAlpha", in2: "lower", operator: "out", result: "topEdge" }), _jsx("feFlood", { floodColor: `var(--kind-ui-${family}-clay-light, #fff)`, floodOpacity: 0.65 }), _jsx("feComposite", { in2: "topEdge", operator: "in", result: "light" }), _jsx("feOffset", { in: "SourceAlpha", dx: 0, dy: -2, result: "upper" }), _jsx("feComposite", { in: "SourceAlpha", in2: "upper", operator: "out", result: "bottomEdge" }), _jsx("feFlood", { floodColor: `var(--kind-ui-${family}-clay-shade, #17212b)`, floodOpacity: 0.38 }), _jsx("feComposite", { in2: "bottomEdge", operator: "in", result: "shade" }), _jsxs("feMerge", { children: [_jsx("feMergeNode", { in: "SourceGraphic" }), _jsx("feMergeNode", { in: "shade" }), _jsx("feMergeNode", { in: "light" })] })] })) : (_jsxs(_Fragment, { children: [_jsx("feGaussianBlur", { in: "SourceGraphic", stdDeviation: 2.5, result: "halo" }), _jsx("feFlood", { floodOpacity: `var(--kind-ui-${family}-glow-opacity, 0.6)`, result: "strength" }), _jsx("feComposite", { in: "halo", in2: "strength", operator: "in", result: "softHalo" }), _jsx("feMorphology", { in: "SourceAlpha", operator: "erode", radius: 0.8, result: "inside" }), _jsx("feComposite", { in: "SourceAlpha", in2: "inside", operator: "out", result: "edge" }), _jsx("feFlood", { floodColor: `var(--kind-ui-${family}-glow-light, #fff)`, floodOpacity: 0.45 }), _jsx("feComposite", { in2: "edge", operator: "in", result: "light" }), _jsxs("feMerge", { children: [_jsx("feMergeNode", { in: "softHalo" }), _jsx("feMergeNode", { in: "SourceGraphic" }), _jsx("feMergeNode", { in: "light" })] })] })) }));
7
+ }
@@ -0,0 +1,19 @@
1
+ import { type ComponentPropsWithRef, type ReactNode } from "react";
2
+ import type { TooltipContentProps as UpstreamTooltipContentProps } from "recharts";
3
+ export type TooltipContentProps = Omit<ComponentPropsWithRef<"div">, "children"> & {
4
+ /** Pass the upstream content callback's props here so engine-only props never reach the DOM. */
5
+ tooltip: UpstreamTooltipContentProps;
6
+ missingValue?: ReactNode;
7
+ /** Opt in to decorative rolling digits for finite numeric text values. Default: off. */
8
+ valueAnimation?: "shuffle";
9
+ /** Omit the heading; series labels and values remain accessible. */
10
+ hideLabel?: boolean;
11
+ /** Omit the decorative marker, including a configured icon. */
12
+ hideIndicator?: boolean;
13
+ /** Defaults to the existing slim line marker. Configured icons take precedence. */
14
+ indicator?: "dot" | "line" | "dashed";
15
+ /** Stable metadata/visibility identity for an item, e.g. a pie category payload ID. */
16
+ itemKey?: (entry: UpstreamTooltipContentProps["payload"][number]) => string;
17
+ };
18
+ /** Default tooltip UI using the containing chart's labels, formats, colors and visibility. */
19
+ export declare function TooltipContent({ tooltip, missingValue, valueAnimation, itemKey, hideLabel, hideIndicator, indicator, ...props }: TooltipContentProps): import("react").JSX.Element | null;
@@ -0,0 +1,60 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { use } from "react";
4
+ import { useChart } from "./chart-context.js";
5
+ import { LineInteraction } from "./line-chart.js";
6
+ import { TooltipNumber } from "./tooltip-number.js";
7
+ /** Default tooltip UI using the containing chart's labels, formats, colors and visibility. */
8
+ export function TooltipContent({ tooltip, missingValue = "No data", valueAnimation, itemKey, hideLabel = false, hideIndicator = false, indicator = "line", ...props }) {
9
+ const { config, visibleSeries } = useChart();
10
+ const line = use(LineInteraction);
11
+ const identity = (entry) => itemKey?.(entry) ??
12
+ (entry.graphicalItemId ? line?.seriesKeys.get(entry.graphicalItemId) : undefined) ??
13
+ String(entry.dataKey ?? entry.name);
14
+ const { active, payload, label, formatter, labelFormatter, accessibilityLayer } = tooltip;
15
+ const entries = active
16
+ ? payload.filter((item) => item.type !== "none" &&
17
+ !item.hide &&
18
+ (visibleSeries === undefined || visibleSeries.includes(identity(item))))
19
+ : [];
20
+ if (!entries.some((entry) => entry.value != null))
21
+ return null;
22
+ let hasVisibleValue = false;
23
+ const items = entries.map((entry, index) => {
24
+ const key = identity(entry);
25
+ const item = Object.hasOwn(config, key) ? config[key] : undefined;
26
+ let name = item?.label ?? entry.name ?? key;
27
+ let value = missingValue;
28
+ if (entry.value != null) {
29
+ const format = entry.formatter ?? formatter;
30
+ if (format) {
31
+ const result = format(entry.value, entry.name, entry, index, entries);
32
+ if (result == null)
33
+ return null;
34
+ if (Array.isArray(result))
35
+ [value, name] = result;
36
+ else
37
+ value = result;
38
+ }
39
+ else
40
+ value = item?.formatValue
41
+ ? item.formatValue(entry.value)
42
+ : Array.isArray(entry.value)
43
+ ? entry.value.join(" – ")
44
+ : entry.value;
45
+ hasVisibleValue = true;
46
+ }
47
+ return (_jsxs("li", { "data-kind-ui": "chart-tooltip-item", "data-series": key, children: [!hideIndicator &&
48
+ (item?.icon ? (_jsx("span", { "aria-hidden": "true", "data-kind-ui": "chart-icon", children: _jsx(item.icon, {}) })) : (_jsx("span", { "aria-hidden": "true", "data-kind-ui": "chart-indicator", "data-indicator": indicator, style: {
49
+ "--kind-ui-chart-indicator-color": item
50
+ ? `var(--color-${key})`
51
+ : (entry.color ?? "currentColor"),
52
+ } }))), _jsx("span", { children: name }), _jsx("strong", { "data-kind-ui": "chart-tooltip-value", children: valueAnimation === "shuffle" &&
53
+ typeof entry.value === "number" &&
54
+ Number.isFinite(entry.value) &&
55
+ (typeof value === "string" || (typeof value === "number" && Number.isFinite(value))) ? (_jsx(TooltipNumber, { value: value })) : (value) })] }, entry.graphicalItemId ?? `${key}-${index}`));
56
+ });
57
+ if (!hasVisibleValue)
58
+ return null;
59
+ return (_jsx("div", { role: accessibilityLayer ? "status" : undefined, "aria-live": accessibilityLayer ? "assertive" : undefined, "aria-atomic": "true", ...props, "data-kind-ui": "chart-tooltip", children: entries.length > 0 && (_jsxs(_Fragment, { children: [!hideLabel && (_jsx("strong", { "data-kind-ui": "chart-tooltip-label", children: labelFormatter ? labelFormatter(label, entries) : label })), _jsx("ul", { "data-kind-ui": "chart-tooltip-list", children: items })] })) }));
60
+ }
@@ -0,0 +1,4 @@
1
+ /** Private presentation only: formatters and native tooltip selection remain upstream. */
2
+ export declare function TooltipNumber({ value }: {
3
+ value: string | number;
4
+ }): string | number | import("react").JSX.Element;
@@ -0,0 +1,68 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { animate, motion, useMotionValue, useTransform } from "motion/react";
4
+ import { useLayoutEffect, useRef, useSyncExternalStore } from "react";
5
+ const query = "(prefers-reduced-motion: reduce)";
6
+ function subscribe(change) {
7
+ const media = window.matchMedia(query);
8
+ media.addEventListener("change", change);
9
+ return () => media.removeEventListener("change", change);
10
+ }
11
+ const snapshot = () => window.matchMedia(query).matches;
12
+ const serverSnapshot = () => true;
13
+ const reel = Array.from({ length: 30 }, (_, index) => index);
14
+ // Keep a bounded repeating reel. Interrupted transitions start at the currently painted digit.
15
+ function Digit({ digit }) {
16
+ // Newly opened tooltips should paint their actual value immediately.
17
+ // Subsequent value updates still animate from the painted digit.
18
+ const position = useMotionValue(digit + 10);
19
+ const y = useTransform(position, (value) => `${-value}lh`);
20
+ useLayoutEffect(() => {
21
+ const current = position.get();
22
+ const target = [digit, digit + 10, digit + 20].reduce((closest, next) => Math.abs(next - current) < Math.abs(closest - current) ? next : closest);
23
+ const controls = animate(position, target, {
24
+ duration: 0.32,
25
+ ease: [0.22, 1, 0.36, 1],
26
+ onComplete: () => position.set(digit + 10),
27
+ });
28
+ return () => controls.stop();
29
+ }, [digit, position]);
30
+ return (_jsx("span", { "data-kind-ui": "tooltip-digit", children: _jsx(motion.span, { "data-kind-ui": "tooltip-digit-reel", style: { y }, children: reel.map((index) => (_jsx("span", { children: index % 10 }, index))) }) }));
31
+ }
32
+ function RollingNumber({ text }) {
33
+ const final = useRef(null);
34
+ const widest = useRef(0);
35
+ const width = useMotionValue("auto");
36
+ useLayoutEffect(() => {
37
+ const node = final.current;
38
+ if (!node)
39
+ return;
40
+ const measure = () => {
41
+ const next = node.getBoundingClientRect().width;
42
+ if (next <= widest.current)
43
+ return;
44
+ // Retain the widest value without revealing it through a clipping width.
45
+ width.set(next);
46
+ widest.current = next;
47
+ };
48
+ measure();
49
+ const observer = new ResizeObserver(measure);
50
+ observer.observe(node);
51
+ return () => {
52
+ observer.disconnect();
53
+ };
54
+ }, [width]);
55
+ const characters = text.match(/[0-9]|[^0-9]+/g) ?? [];
56
+ let place = characters.filter((character) => /^[0-9]$/.test(character)).length;
57
+ return (_jsxs(motion.span, { "data-kind-ui": "tooltip-number", style: { width }, children: [_jsx("span", { ref: final, "data-kind-ui": "tooltip-number-final", children: text }), _jsx("span", { "aria-hidden": "true", "data-kind-ui": "tooltip-number-visual", children: characters.map((character) => /^[0-9]$/.test(character) ? (_jsx(Digit, { digit: Number(character) }, `digit-${--place}`)) : (_jsx("span", { children: character }, `text-${place}-${character}`))) })] }));
58
+ }
59
+ /** Private presentation only: formatters and native tooltip selection remain upstream. */
60
+ export function TooltipNumber({ value }) {
61
+ const reduced = useSyncExternalStore(subscribe, snapshot, serverSnapshot);
62
+ const text = String(value);
63
+ // Mixed scripts, non-ASCII digits and bidi text keep their original shaping/order.
64
+ const unsupported = !/[0-9]/.test(text) ||
65
+ /\p{Decimal_Number}/u.test(text.replace(/[0-9]/g, "")) ||
66
+ /[\u0590-\u08ff\u200e\u200f\u202a-\u202e\u2066-\u2069]/.test(text);
67
+ return reduced || unsupported ? value : _jsx(RollingNumber, { text: text });
68
+ }
@@ -0,0 +1,29 @@
1
+ import { type ComponentPropsWithRef, type ReactNode, type Ref } from "react";
2
+ import { type TooltipProps as EngineTooltipProps } from "recharts";
3
+ import { type TooltipContentProps } from "./tooltip-content.js";
4
+ export type TooltipProps = Omit<EngineTooltipProps, "position" | "isAnimationActive" | "portal" | "allowEscapeViewBox" | "reverseDirection" | "useTranslate3d"> & {
5
+ /** Ref and native attributes for Kind's measured positioning element. */
6
+ ref?: Ref<HTMLDivElement>;
7
+ frameProps?: Omit<ComponentPropsWithRef<"div">, "children" | "ref">;
8
+ maxWidth?: number;
9
+ /** Resolves category identity before the existing series-key fallback. */
10
+ itemKey?: TooltipContentProps["itemKey"];
11
+ /** Opt in on Kind's default content; custom content owns its own animation. */
12
+ valueAnimation?: TooltipContentProps["valueAnimation"];
13
+ };
14
+ export type TooltipFrameProps = {
15
+ x: number;
16
+ y: number;
17
+ maxX: number;
18
+ maxY: number;
19
+ children: ReactNode;
20
+ ref?: Ref<HTMLDivElement>;
21
+ style: ComponentPropsWithRef<"div">["style"];
22
+ frameProps: TooltipProps["frameProps"];
23
+ };
24
+ export declare function StaticTooltipFrame({ x, y, ref, style, frameProps, children }: TooltipFrameProps): import("react").JSX.Element;
25
+ export declare function TooltipBase({ ref, content, frameProps, maxWidth, itemKey, valueAnimation, Frame, ...props }: TooltipProps & {
26
+ Frame?: (props: TooltipFrameProps) => ReactNode;
27
+ }): import("react").JSX.Element;
28
+ /** Measured and bounded content; the engine owns payload, selection and Escape dismissal. */
29
+ export declare function Tooltip(props: TooltipProps): import("react").JSX.Element;