Skip to content

Commit 16585da

Browse files
Merge pull request #55 from TanStack/taren/add-crosshair
Add crosshair and shared cursor primitives
2 parents 1e8c048 + 7aab62c commit 16585da

155 files changed

Lines changed: 13696 additions & 2118 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.changeset/brave-tooltips-expand.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Tooltip `format` and `formatGroup` now receive the same content context as
1515
legend, and spatial-index extension callbacks move their supporting values
1616
into named context objects.
1717

18-
`ruleX` and `ruleY` now expose presentation-only focus points, so
18+
`ruleX` and `ruleY` now expose axis-specific presentation-only focus anchors, so
1919
`whenFocused(..., { match: 'x' })` and `whenFocused(..., { match: 'y' })` can
2020
reveal focused guide rules without making them interaction or tooltip targets.
2121

.changeset/bright-cursors-cross.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@tanstack/charts': minor
3+
---
4+
5+
Add renderer-native crosshair rules, categorical cursor bands, labels, and optional intersection markers plus shared focus/free cursor controllers across SVG, Canvas, motion, and React Native rendering. Focus-filtered rule marks now use non-interactive semantic anchors, built-in axis focus modes select the painted mark under the pointer before grouping or snapping, and keyed motion guides remain active through scene updates.

API-FRICTION.md

Lines changed: 304 additions & 97 deletions
Large diffs are not rendered by default.

benchmarks/bundle-size/universal-baseline.json

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,44 +3,44 @@
33
"policy": "Exact minified and gzip output for entries that optional features must not affect. Review every change before updating.",
44
"bundles": {
55
"D3-scale line scene": {
6-
"bytes": 43460,
7-
"gzip": 16624
6+
"bytes": 43679,
7+
"gzip": 16692
88
},
99
"D3-scale line + static SVG": {
10-
"bytes": 47882,
11-
"gzip": 18219
10+
"bytes": 48140,
11+
"gzip": 18322
1212
},
1313
"Representative marks": {
14-
"bytes": 64027,
15-
"gzip": 23441
14+
"bytes": 64215,
15+
"gzip": 23509
1616
},
1717
"TanStack DOM host": {
18-
"bytes": 52638,
19-
"gzip": 18983
18+
"bytes": 61658,
19+
"gzip": 21742
2020
},
2121
"React adapter": {
22-
"bytes": 54837,
23-
"gzip": 19813
22+
"bytes": 63858,
23+
"gzip": 22527
2424
},
2525
"React line consumer": {
26-
"bytes": 77572,
27-
"gzip": 28813
26+
"bytes": 86604,
27+
"gzip": 31511
2828
},
2929
"Compact-scale line scene": {
30-
"bytes": 25919,
31-
"gzip": 9529
30+
"bytes": 26139,
31+
"gzip": 9605
3232
},
3333
"React compact-scale line consumer": {
34-
"bytes": 60079,
35-
"gzip": 21717
34+
"bytes": 69102,
35+
"gzip": 24527
3636
},
3737
"Custom-scale line scene": {
38-
"bytes": 24103,
39-
"gzip": 8801
38+
"bytes": 24323,
39+
"gzip": 8875
4040
},
4141
"D3 linear-scale line scene": {
42-
"bytes": 43392,
43-
"gzip": 16588
42+
"bytes": 43611,
43+
"gzip": 16655
4444
}
4545
}
4646
}

benchmarks/comparison/bundle-baseline.json

Lines changed: 62 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"schemaVersion": 3,
3-
"generatedAt": "2026-08-05T17:26:11.302Z",
3+
"generatedAt": "2026-08-05T18:27:54.234Z",
44
"packageVersions": {
55
"tanstack": "0.6.5",
66
"chartjs": "4.5.1",
@@ -11,7 +11,7 @@
1111
"sources": {
1212
"tanstack": {
1313
"kind": "workspace",
14-
"revision": "2688b431ae10fe42a9132a2e1f7c88d58cb0cd28"
14+
"revision": "b261d4575b37e1fe7d50183434c1d976205af378"
1515
},
1616
"chartjs": {
1717
"kind": "package",
@@ -44,88 +44,88 @@
4444
},
4545
"bundles": {
4646
"tanstack-line-basic": {
47-
"minifiedBytes": 86395,
48-
"gzipBytes": 32291,
49-
"brotliBytes": 28544,
50-
"incrementalGzipBytes": 32291,
51-
"incrementalBrotliBytes": 28544
47+
"minifiedBytes": 95427,
48+
"gzipBytes": 34986,
49+
"brotliBytes": 30971,
50+
"incrementalGzipBytes": 34986,
51+
"incrementalBrotliBytes": 30971
5252
},
5353
"tanstack-line-interactive": {
54-
"minifiedBytes": 91597,
55-
"gzipBytes": 33900,
56-
"brotliBytes": 29976,
57-
"incrementalGzipBytes": 33900,
58-
"incrementalBrotliBytes": 29976
54+
"minifiedBytes": 100629,
55+
"gzipBytes": 36602,
56+
"brotliBytes": 32368,
57+
"incrementalGzipBytes": 36602,
58+
"incrementalBrotliBytes": 32368
5959
},
6060
"tanstack-line-advanced": {
61-
"minifiedBytes": 98780,
62-
"gzipBytes": 36151,
63-
"brotliBytes": 31926,
64-
"incrementalGzipBytes": 36151,
65-
"incrementalBrotliBytes": 31926
61+
"minifiedBytes": 107817,
62+
"gzipBytes": 38978,
63+
"brotliBytes": 34363,
64+
"incrementalGzipBytes": 38978,
65+
"incrementalBrotliBytes": 34363
6666
},
6767
"tanstack-bar-basic": {
68-
"minifiedBytes": 93405,
69-
"gzipBytes": 34862,
70-
"brotliBytes": 30778,
71-
"incrementalGzipBytes": 34862,
72-
"incrementalBrotliBytes": 30778
68+
"minifiedBytes": 102438,
69+
"gzipBytes": 37627,
70+
"brotliBytes": 33228,
71+
"incrementalGzipBytes": 37627,
72+
"incrementalBrotliBytes": 33228
7373
},
7474
"tanstack-bar-interactive": {
75-
"minifiedBytes": 97462,
76-
"gzipBytes": 36077,
77-
"brotliBytes": 31824,
78-
"incrementalGzipBytes": 36077,
79-
"incrementalBrotliBytes": 31824
75+
"minifiedBytes": 106495,
76+
"gzipBytes": 38864,
77+
"brotliBytes": 34253,
78+
"incrementalGzipBytes": 38864,
79+
"incrementalBrotliBytes": 34253
8080
},
8181
"tanstack-bar-advanced": {
82-
"minifiedBytes": 97801,
83-
"gzipBytes": 36224,
84-
"brotliBytes": 31969,
85-
"incrementalGzipBytes": 36224,
86-
"incrementalBrotliBytes": 31969
82+
"minifiedBytes": 106834,
83+
"gzipBytes": 39006,
84+
"brotliBytes": 34349,
85+
"incrementalGzipBytes": 39006,
86+
"incrementalBrotliBytes": 34349
8787
},
8888
"tanstack-area-basic": {
89-
"minifiedBytes": 90206,
90-
"gzipBytes": 33673,
91-
"brotliBytes": 29886,
92-
"incrementalGzipBytes": 33673,
93-
"incrementalBrotliBytes": 29886
89+
"minifiedBytes": 99241,
90+
"gzipBytes": 36475,
91+
"brotliBytes": 32283,
92+
"incrementalGzipBytes": 36475,
93+
"incrementalBrotliBytes": 32283
9494
},
9595
"tanstack-area-interactive": {
96-
"minifiedBytes": 95412,
97-
"gzipBytes": 35303,
98-
"brotliBytes": 31191,
99-
"incrementalGzipBytes": 35303,
100-
"incrementalBrotliBytes": 31191
96+
"minifiedBytes": 104447,
97+
"gzipBytes": 38120,
98+
"brotliBytes": 33634,
99+
"incrementalGzipBytes": 38120,
100+
"incrementalBrotliBytes": 33634
101101
},
102102
"tanstack-area-advanced": {
103-
"minifiedBytes": 102780,
104-
"gzipBytes": 37708,
105-
"brotliBytes": 33313,
106-
"incrementalGzipBytes": 37708,
107-
"incrementalBrotliBytes": 33313
103+
"minifiedBytes": 111816,
104+
"gzipBytes": 40510,
105+
"brotliBytes": 35667,
106+
"incrementalGzipBytes": 40510,
107+
"incrementalBrotliBytes": 35667
108108
},
109109
"tanstack-scatter-basic": {
110-
"minifiedBytes": 86057,
111-
"gzipBytes": 32196,
112-
"brotliBytes": 28492,
113-
"incrementalGzipBytes": 32196,
114-
"incrementalBrotliBytes": 28492
110+
"minifiedBytes": 95089,
111+
"gzipBytes": 34851,
112+
"brotliBytes": 30881,
113+
"incrementalGzipBytes": 34851,
114+
"incrementalBrotliBytes": 30881
115115
},
116116
"tanstack-scatter-interactive": {
117-
"minifiedBytes": 91259,
118-
"gzipBytes": 33790,
119-
"brotliBytes": 29828,
120-
"incrementalGzipBytes": 33790,
121-
"incrementalBrotliBytes": 29828
117+
"minifiedBytes": 100291,
118+
"gzipBytes": 36504,
119+
"brotliBytes": 32243,
120+
"incrementalGzipBytes": 36504,
121+
"incrementalBrotliBytes": 32243
122122
},
123123
"tanstack-scatter-advanced": {
124-
"minifiedBytes": 91275,
125-
"gzipBytes": 33795,
126-
"brotliBytes": 29824,
127-
"incrementalGzipBytes": 33795,
128-
"incrementalBrotliBytes": 29824
124+
"minifiedBytes": 100307,
125+
"gzipBytes": 36510,
126+
"brotliBytes": 32281,
127+
"incrementalGzipBytes": 36510,
128+
"incrementalBrotliBytes": 32281
129129
},
130130
"chartjs-line-basic": {
131131
"minifiedBytes": 137909,

benchmarks/conformance/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ comparison.
251251

252252
## Current scope
253253

254-
The executable corpus contains 109 paired cases: 75 sourced from Observable
254+
The executable corpus contains 110 paired cases: 76 sourced from Observable
255255
Plot, 23 from Recharts, and 11 from Apache ECharts. It spans the common
256256
cartesian vocabulary plus the high-value catalog beyond it:
257257

@@ -289,7 +289,7 @@ pointer, native horizontal resource scrolling, streaming-window preservation,
289289
synchronized multi-view cursors, a free two-dimensional cursor, continuous
290290
brush selection, wheel zoom and pan, timeline scrubbing, and editable event
291291
ranges. Focus-plus-context uses Plot as its reference. Together with the
292-
original tooltip cases, 16 cases carry executable interaction scenarios.
292+
original tooltip cases, 19 cases carry executable interaction scenarios.
293293

294294
All declared interaction scenarios and the prior 79-case full-corpus visual
295295
matrix pass across both renderers, initial/revised data, 320/640/960 px, and

benchmarks/conformance/cases/117-focus-cursor-motion/case.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
"url": "https://motion.dev/docs/animate"
7171
},
7272
"ai": {
73-
"create": "Create a grouped line chart where the primary datum, its shared-x group, the focused series, unmatched marks, and an external crosshair with axis labels all animate distinctly.",
73+
"create": "Create a grouped line chart where the primary datum, its shared-x group, the focused series, unmatched marks, and a renderer-native crosshair with axis labels all animate distinctly.",
7474
"maintain": "Keep focus semantics in mark states, preserve spring velocity and label alignment during rapid pointer retargeting, and support the same focus movement from the keyboard."
7575
}
7676
}

0 commit comments

Comments
 (0)