Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/focus-ring-options.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tanstack/charts': minor
---

Allow the built-in focus ring to configure its radius, stroke width, fill, and stroke while preserving the existing boolean behavior and defaults.
22 changes: 22 additions & 0 deletions API-FRICTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,7 @@ Each entry records:
| F-292 | Fixed preview paints ignored the selected site theme | Tooling | resolved |
| F-293 | Root scale slots blocked named axes | API | resolved |
| F-294 | Automatic mark renderers imposed shared host plumbing | API | resolved |
| F-295 | Focus ring paint required generated SVG selectors | API | resolved |

## Findings

Expand Down Expand Up @@ -8505,3 +8506,24 @@ Each entry records:
React Native Metro gates, and framework package checks pass. Bundle boundary
checks keep SVG-only entries free of Canvas and measure the opt-in mixed
representative and React consumers at 35.68 KiB and 41.63 KiB gzip.

### F-295 - Focus ring paint required generated SVG selectors

- Status: resolved
- Severity: medium
- Owner: API
- Observed in: Rewardo's TanStack Charts migration and issue #94
- Friction: the built-in primary-point ring exposed only a boolean definition
option. Rewardo had to target `.ts-chart__focus-layer--default circle` to
reduce the fixed 5-pixel radius, tying application styling to generated SVG
structure and leaving Canvas and React Native without the same control.
- Decision: extend `focusRing` to accept a reusable `ChartFocusRingOptions`
object with radius, stroke width, fill, and stroke. Preserve `true`, `false`,
and every existing default. An omitted stroke keeps each point's resolved
series color.
- Verification: scene, SVG, Canvas, and React Native tests cover configured
geometry and paint, series-color fallback, keyboard focus, and hidden
accessibility presentation. The catalog's pointer-tooltip case uses the
object form, and the reference docs record the complete contract. Locked
universal consumers add 65-79 minified bytes and 25-36 gzip bytes; the
reviewed bundle baselines and budgets pass.
40 changes: 20 additions & 20 deletions benchmarks/bundle-size/universal-baseline.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,44 +3,44 @@
"policy": "Exact minified and gzip output for entries that optional features must not affect. Review every change before updating.",
"bundles": {
"D3-scale line scene": {
"bytes": 50813,
"gzip": 19070
"bytes": 50878,
"gzip": 19095
},
"D3-scale line + static SVG": {
"bytes": 55544,
"gzip": 20776
"bytes": 55612,
"gzip": 20808
},
"Representative marks": {
"bytes": 75617,
"gzip": 27582
"bytes": 75683,
"gzip": 27615
},
"TanStack DOM host": {
"bytes": 74947,
"gzip": 26053
"bytes": 75026,
"gzip": 26087
},
"React adapter": {
"bytes": 77130,
"gzip": 26831
"bytes": 77209,
"gzip": 26866
},
"React line consumer": {
"bytes": 100766,
"gzip": 36222
"bytes": 100839,
"gzip": 36251
},
"Compact-scale line scene": {
"bytes": 33265,
"gzip": 11935
"bytes": 33336,
"gzip": 11969
},
"React compact-scale line consumer": {
"bytes": 83266,
"gzip": 29144
"bytes": 83345,
"gzip": 29173
},
"Custom-scale line scene": {
"bytes": 31447,
"gzip": 11193
"bytes": 31518,
"gzip": 11229
},
"D3 linear-scale line scene": {
"bytes": 50745,
"gzip": 19032
"bytes": 50810,
"gzip": 19057
}
}
}
128 changes: 64 additions & 64 deletions benchmarks/comparison/bundle-baseline.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"schemaVersion": 4,
"generatedAt": "2026-08-26T21:51:12.832Z",
"generatedAt": "2026-08-27T22:10:29.425Z",
"packageVersions": {
"tanstack": "0.15.0",
"tanstack": "0.16.0",
"chartjs": "4.5.1",
"echarts": "6.1.0",
"recharts": "3.10.1",
Expand All @@ -11,8 +11,8 @@
"sources": {
"tanstack": {
"kind": "workspace",
"revision": "3df87d71f0305e5a450c10b66940f76f3e14259a",
"inputDigest": "sha256:b1016e599e63d05e1647b9d27adabaaed7a38bb44dac8d6ba0fef06b8b8bd38e"
"revision": "cb1779249a6803d591526f7f4e42a20a40e11f4f",
"inputDigest": "sha256:f269a4edd2c1aea574be0de98bc6dff87ad5044501cb4d0a65c4cb565ad4c2ae"
},
"chartjs": {
"kind": "package",
Expand Down Expand Up @@ -45,88 +45,88 @@
},
"bundles": {
"tanstack-line-basic": {
"minifiedBytes": 110431,
"gzipBytes": 39891,
"brotliBytes": 35325,
"incrementalGzipBytes": 39891,
"incrementalBrotliBytes": 35325
"minifiedBytes": 110507,
"gzipBytes": 39915,
"brotliBytes": 35396,
"incrementalGzipBytes": 39915,
"incrementalBrotliBytes": 35396
},
"tanstack-line-interactive": {
"minifiedBytes": 115872,
"gzipBytes": 41648,
"brotliBytes": 36746,
"incrementalGzipBytes": 41648,
"incrementalBrotliBytes": 36746
"minifiedBytes": 115948,
"gzipBytes": 41682,
"brotliBytes": 36752,
"incrementalGzipBytes": 41682,
"incrementalBrotliBytes": 36752
},
"tanstack-line-advanced": {
"minifiedBytes": 123062,
"gzipBytes": 43974,
"brotliBytes": 38764,
"incrementalGzipBytes": 43974,
"incrementalBrotliBytes": 38764
"minifiedBytes": 123138,
"gzipBytes": 43996,
"brotliBytes": 38742,
"incrementalGzipBytes": 43996,
"incrementalBrotliBytes": 38742
},
"tanstack-bar-basic": {
"minifiedBytes": 119225,
"gzipBytes": 43210,
"brotliBytes": 38168,
"incrementalGzipBytes": 43210,
"incrementalBrotliBytes": 38168
"minifiedBytes": 119300,
"gzipBytes": 43240,
"brotliBytes": 38149,
"incrementalGzipBytes": 43240,
"incrementalBrotliBytes": 38149
},
"tanstack-bar-interactive": {
"minifiedBytes": 123521,
"gzipBytes": 44585,
"brotliBytes": 39223,
"incrementalGzipBytes": 44585,
"incrementalBrotliBytes": 39223
"minifiedBytes": 123596,
"gzipBytes": 44613,
"brotliBytes": 39219,
"incrementalGzipBytes": 44613,
"incrementalBrotliBytes": 39219
},
"tanstack-bar-advanced": {
"minifiedBytes": 123860,
"gzipBytes": 44735,
"brotliBytes": 39349,
"incrementalGzipBytes": 44735,
"incrementalBrotliBytes": 39349
"minifiedBytes": 123935,
"gzipBytes": 44758,
"brotliBytes": 39385,
"incrementalGzipBytes": 44758,
"incrementalBrotliBytes": 39385
},
"tanstack-area-basic": {
"minifiedBytes": 115640,
"gzipBytes": 41867,
"brotliBytes": 37073,
"incrementalGzipBytes": 41867,
"incrementalBrotliBytes": 37073
"minifiedBytes": 115714,
"gzipBytes": 41897,
"brotliBytes": 37085,
"incrementalGzipBytes": 41897,
"incrementalBrotliBytes": 37085
},
"tanstack-area-interactive": {
"minifiedBytes": 121085,
"gzipBytes": 43594,
"brotliBytes": 38493,
"incrementalGzipBytes": 43594,
"incrementalBrotliBytes": 38493
"minifiedBytes": 121159,
"gzipBytes": 43630,
"brotliBytes": 38508,
"incrementalGzipBytes": 43630,
"incrementalBrotliBytes": 38508
},
"tanstack-area-advanced": {
"minifiedBytes": 128457,
"gzipBytes": 46057,
"brotliBytes": 40527,
"incrementalGzipBytes": 46057,
"incrementalBrotliBytes": 40527
"minifiedBytes": 128530,
"gzipBytes": 46084,
"brotliBytes": 40565,
"incrementalGzipBytes": 46084,
"incrementalBrotliBytes": 40565
},
"tanstack-scatter-basic": {
"minifiedBytes": 111460,
"gzipBytes": 40266,
"brotliBytes": 35596,
"incrementalGzipBytes": 40266,
"incrementalBrotliBytes": 35596
"minifiedBytes": 111536,
"gzipBytes": 40299,
"brotliBytes": 35718,
"incrementalGzipBytes": 40299,
"incrementalBrotliBytes": 35718
},
"tanstack-scatter-interactive": {
"minifiedBytes": 116901,
"gzipBytes": 42015,
"brotliBytes": 36976,
"incrementalGzipBytes": 42015,
"incrementalBrotliBytes": 36976
"minifiedBytes": 116977,
"gzipBytes": 42045,
"brotliBytes": 36987,
"incrementalGzipBytes": 42045,
"incrementalBrotliBytes": 36987
},
"tanstack-scatter-advanced": {
"minifiedBytes": 116917,
"gzipBytes": 42020,
"brotliBytes": 37012,
"incrementalGzipBytes": 42020,
"incrementalBrotliBytes": 37012
"minifiedBytes": 116993,
"gzipBytes": 42050,
"brotliBytes": 37016,
"incrementalGzipBytes": 42050,
"incrementalBrotliBytes": 37016
},
"chartjs-line-basic": {
"minifiedBytes": 137909,
Expand Down
5 changes: 5 additions & 0 deletions benchmarks/conformance/cases/34-pointer-tooltip/example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ export function createExampleChart({ revision = 0 }: ChartOptions = {}) {
},
},
{
focusRing: {
radius: 4,
strokeWidth: 2,
fill: '#ffffff',
},
keyboard: true,
tooltip: { use: tooltip, ...interactiveTooltip },
},
Expand Down
Loading