layerchart 2.0.0-next.59 → 2.0.0-next.60

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 (133) hide show
  1. package/dist/bench/GeoBench.svelte +1 -1
  2. package/dist/components/AnnotationLine.svelte +1 -3
  3. package/dist/components/AnnotationPoint.svelte +5 -11
  4. package/dist/components/BrushContext.svelte.test.js +21 -14
  5. package/dist/components/Chart.svelte +50 -17
  6. package/dist/components/Chart.svelte.d.ts +1 -1
  7. package/dist/components/ChartChildren.svelte +56 -30
  8. package/dist/components/ChartChildren.svelte.d.ts +12 -12
  9. package/dist/components/ComputedStyles.svelte +1 -1
  10. package/dist/components/Grid.svelte +14 -11
  11. package/dist/components/Highlight.svelte +10 -8
  12. package/dist/components/Highlight.svelte.d.ts +1 -1
  13. package/dist/components/Hull.svelte +1 -1
  14. package/dist/components/Link.svelte +8 -3
  15. package/dist/components/TransformContext.svelte.d.ts +1 -1
  16. package/dist/components/Voronoi.svelte +1 -1
  17. package/dist/components/__screenshots__/BrushContext.svelte.test.ts/BrushContext-external-sync--x-y-props--should-clear-brush-when-x-prop-changes-to--null--null--1.png +0 -0
  18. package/dist/components/__screenshots__/BrushContext.svelte.test.ts/BrushContext-external-sync--x-y-props--should-clear-brush-when-x-prop-changes-to--null--null--2.png +0 -0
  19. package/dist/components/__screenshots__/BrushContext.svelte.test.ts/BrushContext-external-sync--x-y-props--should-show-brush-when-x-prop-is-provided-with-a-sub-domain-1.png +0 -0
  20. package/dist/components/__screenshots__/BrushContext.svelte.test.ts/BrushContext-external-sync--x-y-props--should-show-brush-when-x-prop-is-provided-with-a-sub-domain-2.png +0 -0
  21. package/dist/components/__screenshots__/BrushContext.svelte.test.ts/BrushContext-external-sync--x-y-props--should-update-brush-width-when-x-prop-changes-1.png +0 -0
  22. package/dist/components/__screenshots__/BrushContext.svelte.test.ts/BrushContext-external-sync--x-y-props--should-update-brush-width-when-x-prop-changes-2.png +0 -0
  23. package/dist/components/__screenshots__/BrushContext.svelte.test.ts/BrushContext-programmatic-control-should-clear-brush-when-reset-programmatically-1.png +0 -0
  24. package/dist/components/__screenshots__/BrushContext.svelte.test.ts/BrushContext-programmatic-control-should-clear-brush-when-reset-programmatically-2.png +0 -0
  25. package/dist/components/__screenshots__/BrushContext.svelte.test.ts/BrushContext-programmatic-control-should-compute-correct-pixel-width-for-brush-move---1.png +0 -0
  26. package/dist/components/__screenshots__/BrushContext.svelte.test.ts/BrushContext-programmatic-control-should-compute-correct-pixel-width-for-brush-move---2.png +0 -0
  27. package/dist/components/__screenshots__/BrushContext.svelte.test.ts/BrushContext-programmatic-control-should-move-only-y-when-x-is-not-specified-1.png +0 -0
  28. package/dist/components/__screenshots__/BrushContext.svelte.test.ts/BrushContext-programmatic-control-should-move-only-y-when-x-is-not-specified-2.png +0 -0
  29. package/dist/components/__screenshots__/BrushContext.svelte.test.ts/BrushContext-programmatic-control-should-select-full-domain-with-selectAll-1.png +0 -0
  30. package/dist/components/__screenshots__/BrushContext.svelte.test.ts/BrushContext-programmatic-control-should-select-full-domain-with-selectAll-2.png +0 -0
  31. package/dist/components/__screenshots__/BrushContext.svelte.test.ts/BrushContext-programmatic-control-should-show-brush-when-moved-programmatically-via-context-1.png +0 -0
  32. package/dist/components/__screenshots__/BrushContext.svelte.test.ts/BrushContext-programmatic-control-should-show-brush-when-moved-programmatically-via-context-2.png +0 -0
  33. package/dist/components/__screenshots__/BrushContext.svelte.test.ts/BrushContext-programmatic-control-should-update-width-when-brush-move---is-called-again-1.png +0 -0
  34. package/dist/components/__screenshots__/BrushContext.svelte.test.ts/BrushContext-programmatic-control-should-update-width-when-brush-move---is-called-again-2.png +0 -0
  35. package/dist/components/__screenshots__/BrushContext.svelte.test.ts/BrushContext-rendering-should-render-brush-context-when-brush-is-enabled-1.png +0 -0
  36. package/dist/components/__screenshots__/BrushContext.svelte.test.ts/BrushContext-rendering-should-render-brush-context-when-brush-is-enabled-2.png +0 -0
  37. package/dist/components/__screenshots__/BrushContext.svelte.test.ts/BrushContext-zoomOnBrush-with-onBrushEnd-should-pass-brush-domain-values-to-onBrushEnd-before-resetting-1.png +0 -0
  38. package/dist/components/__screenshots__/BrushContext.svelte.test.ts/BrushContext-zoomOnBrush-with-onBrushEnd-should-pass-brush-domain-values-to-onBrushEnd-before-resetting-2.png +0 -0
  39. package/dist/components/charts/BarChart.svelte.test.js +8 -3
  40. package/dist/components/charts/DefaultTooltip.svelte +11 -2
  41. package/dist/components/charts/DefaultTooltip.svelte.test.js +19 -8
  42. package/dist/components/charts/LineChart.svelte.test.js +5 -2
  43. package/dist/components/charts/__screenshots__/BarChart.svelte.test.ts/BarChart-legend-series-toggle-adjusts-group-scale-should-adjust-grouped-bar-widths-when-series-are-toggled-via-legend-1.png +0 -0
  44. package/dist/components/charts/__screenshots__/BarChart.svelte.test.ts/BarChart-legend-series-toggle-adjusts-group-scale-should-adjust-grouped-bar-widths-when-series-are-toggled-via-legend-2.png +0 -0
  45. package/dist/components/charts/__screenshots__/DefaultTooltip.svelte.test.ts/DefaultTooltip-AreaChart--multi-series--quadtree-x-mode--should-fade-non-highlighted-tooltip-series-items-on-hover-1.png +0 -0
  46. package/dist/components/charts/__screenshots__/DefaultTooltip.svelte.test.ts/DefaultTooltip-AreaChart--multi-series--quadtree-x-mode--should-fade-non-highlighted-tooltip-series-items-on-hover-2.png +0 -0
  47. package/dist/components/charts/__screenshots__/DefaultTooltip.svelte.test.ts/DefaultTooltip-AreaChart--multi-series--quadtree-x-mode--should-show-header-and-all-series-items-1.png +0 -0
  48. package/dist/components/charts/__screenshots__/DefaultTooltip.svelte.test.ts/DefaultTooltip-AreaChart--multi-series--quadtree-x-mode--should-show-header-and-all-series-items-2.png +0 -0
  49. package/dist/components/charts/__screenshots__/DefaultTooltip.svelte.test.ts/DefaultTooltip-AreaChart--multi-series--quadtree-x-mode--should-show-series-colors-in-tooltip-items-1.png +0 -0
  50. package/dist/components/charts/__screenshots__/DefaultTooltip.svelte.test.ts/DefaultTooltip-AreaChart--multi-series--quadtree-x-mode--should-show-series-colors-in-tooltip-items-2.png +0 -0
  51. package/dist/components/charts/__screenshots__/DefaultTooltip.svelte.test.ts/DefaultTooltip-AreaChart--multi-series--quadtree-x-mode--should-show-single-series-without-total-1.png +0 -0
  52. package/dist/components/charts/__screenshots__/DefaultTooltip.svelte.test.ts/DefaultTooltip-AreaChart--multi-series--quadtree-x-mode--should-show-single-series-without-total-2.png +0 -0
  53. package/dist/components/charts/__screenshots__/DefaultTooltip.svelte.test.ts/DefaultTooltip-LineChart--multi-series--quadtree-x-mode--should-show-header-and-all-series-items-1.png +0 -0
  54. package/dist/components/charts/__screenshots__/DefaultTooltip.svelte.test.ts/DefaultTooltip-LineChart--multi-series--quadtree-x-mode--should-show-header-and-all-series-items-2.png +0 -0
  55. package/dist/components/charts/__screenshots__/DefaultTooltip.svelte.test.ts/DefaultTooltip-ScatterChart--single-point--quadtree-mode--should-show-series-header-for-multi-series-1.png +0 -0
  56. package/dist/components/charts/__screenshots__/DefaultTooltip.svelte.test.ts/DefaultTooltip-ScatterChart--single-point--quadtree-mode--should-show-series-header-for-multi-series-2.png +0 -0
  57. package/dist/components/charts/__screenshots__/DefaultTooltip.svelte.test.ts/DefaultTooltip-ScatterChart--single-point--quadtree-mode--should-show-x--y--and-r-items-when-r-is-configured-1.png +0 -0
  58. package/dist/components/charts/__screenshots__/DefaultTooltip.svelte.test.ts/DefaultTooltip-ScatterChart--single-point--quadtree-mode--should-show-x--y--and-r-items-when-r-is-configured-2.png +0 -0
  59. package/dist/components/charts/__screenshots__/DefaultTooltip.svelte.test.ts/DefaultTooltip-ScatterChart--single-point--quadtree-mode--should-show-x-and-y-items-in-tooltip-1.png +0 -0
  60. package/dist/components/charts/__screenshots__/DefaultTooltip.svelte.test.ts/DefaultTooltip-ScatterChart--single-point--quadtree-mode--should-show-x-and-y-items-in-tooltip-2.png +0 -0
  61. package/dist/components/charts/__screenshots__/LineChart.svelte.test.ts/LineChart-tooltip-should-prefer-cScale-color-over-default-series-color-when-cScale-is-explicitly-provided-1.png +0 -0
  62. package/dist/components/charts/__screenshots__/LineChart.svelte.test.ts/LineChart-tooltip-should-prefer-cScale-color-over-default-series-color-when-cScale-is-explicitly-provided-2.png +0 -0
  63. package/dist/components/force/index.d.ts +2 -0
  64. package/dist/components/force/index.js +2 -0
  65. package/dist/components/{GeoCircle.svelte → geo/GeoCircle.svelte} +2 -2
  66. package/dist/components/{GeoCircle.svelte.d.ts → geo/GeoCircle.svelte.d.ts} +1 -1
  67. package/dist/components/{GeoClipPath.svelte → geo/GeoClipPath.svelte} +5 -5
  68. package/dist/components/{GeoClipPath.svelte.d.ts → geo/GeoClipPath.svelte.d.ts} +2 -2
  69. package/dist/components/{GeoEdgeFade.svelte → geo/GeoEdgeFade.svelte} +4 -4
  70. package/dist/components/{GeoEdgeFade.svelte.d.ts → geo/GeoEdgeFade.svelte.d.ts} +2 -2
  71. package/dist/components/{GeoLegend.svelte → geo/GeoLegend.svelte} +3 -3
  72. package/dist/components/{GeoLegend.svelte.d.ts → geo/GeoLegend.svelte.d.ts} +2 -2
  73. package/dist/components/{GeoPath.svelte → geo/GeoPath.svelte} +6 -6
  74. package/dist/components/{GeoPath.svelte.d.ts → geo/GeoPath.svelte.d.ts} +3 -3
  75. package/dist/components/{GeoPoint.svelte → geo/GeoPoint.svelte} +6 -6
  76. package/dist/components/{GeoPoint.svelte.d.ts → geo/GeoPoint.svelte.d.ts} +2 -2
  77. package/dist/components/{GeoProjection.svelte → geo/GeoProjection.svelte} +3 -3
  78. package/dist/components/{GeoProjection.svelte.d.ts → geo/GeoProjection.svelte.d.ts} +1 -1
  79. package/dist/components/{GeoRaster.svelte → geo/GeoRaster.svelte} +3 -3
  80. package/dist/components/{GeoSpline.svelte → geo/GeoSpline.svelte} +5 -5
  81. package/dist/components/{GeoSpline.svelte.d.ts → geo/GeoSpline.svelte.d.ts} +2 -2
  82. package/dist/components/{GeoTile.svelte → geo/GeoTile.svelte} +5 -5
  83. package/dist/components/{GeoTile.svelte.d.ts → geo/GeoTile.svelte.d.ts} +1 -1
  84. package/dist/components/{GeoVisible.svelte → geo/GeoVisible.svelte} +2 -2
  85. package/dist/components/{Graticule.svelte → geo/Graticule.svelte} +3 -3
  86. package/dist/components/{Graticule.svelte.d.ts → geo/Graticule.svelte.d.ts} +1 -1
  87. package/dist/components/{TileImage.svelte → geo/TileImage.svelte} +3 -3
  88. package/dist/components/{TileImage.svelte.d.ts → geo/TileImage.svelte.d.ts} +1 -1
  89. package/dist/components/geo/index.d.ts +26 -0
  90. package/dist/components/geo/index.js +26 -0
  91. package/dist/components/{Chord.svelte → graph/Chord.svelte} +1 -1
  92. package/dist/components/{Dagre.svelte → graph/Dagre.svelte} +2 -2
  93. package/dist/components/{Ribbon.svelte → graph/Ribbon.svelte} +4 -4
  94. package/dist/components/{Ribbon.svelte.d.ts → graph/Ribbon.svelte.d.ts} +3 -3
  95. package/dist/components/{Sankey.svelte → graph/Sankey.svelte} +1 -1
  96. package/dist/components/graph/index.d.ts +8 -0
  97. package/dist/components/graph/index.js +8 -0
  98. package/dist/components/{Pack.svelte → hierarchy/Pack.svelte} +1 -1
  99. package/dist/components/{Partition.svelte → hierarchy/Partition.svelte} +1 -1
  100. package/dist/components/{Tree.svelte → hierarchy/Tree.svelte} +1 -1
  101. package/dist/components/{Treemap.svelte → hierarchy/Treemap.svelte} +2 -2
  102. package/dist/components/hierarchy/index.d.ts +8 -0
  103. package/dist/components/hierarchy/index.js +8 -0
  104. package/dist/components/index.d.ts +0 -44
  105. package/dist/components/index.js +0 -44
  106. package/dist/components/tooltip/Tooltip.svelte +2 -2
  107. package/dist/components/tooltip/Tooltip.svelte.d.ts +1 -1
  108. package/dist/components/tooltip/TooltipContext.svelte +103 -83
  109. package/dist/components/tooltip/TooltipContext.svelte.d.ts +2 -2
  110. package/dist/force.d.ts +1 -0
  111. package/dist/force.js +1 -0
  112. package/dist/geo.d.ts +1 -0
  113. package/dist/geo.js +1 -0
  114. package/dist/graph.d.ts +1 -0
  115. package/dist/graph.js +1 -0
  116. package/dist/hierarchy.d.ts +1 -0
  117. package/dist/hierarchy.js +1 -0
  118. package/dist/states/chart.svelte.d.ts +2 -2
  119. package/dist/utils/graph/dagre.js +1 -1
  120. package/dist/utils/linkUtils.d.ts +1 -1
  121. package/dist/utils/linkUtils.js +1 -1
  122. package/package.json +25 -1
  123. /package/dist/components/{ForceSimulation.svelte → force/ForceSimulation.svelte} +0 -0
  124. /package/dist/components/{ForceSimulation.svelte.d.ts → force/ForceSimulation.svelte.d.ts} +0 -0
  125. /package/dist/components/{GeoRaster.svelte.d.ts → geo/GeoRaster.svelte.d.ts} +0 -0
  126. /package/dist/components/{GeoVisible.svelte.d.ts → geo/GeoVisible.svelte.d.ts} +0 -0
  127. /package/dist/components/{Chord.svelte.d.ts → graph/Chord.svelte.d.ts} +0 -0
  128. /package/dist/components/{Dagre.svelte.d.ts → graph/Dagre.svelte.d.ts} +0 -0
  129. /package/dist/components/{Sankey.svelte.d.ts → graph/Sankey.svelte.d.ts} +0 -0
  130. /package/dist/components/{Pack.svelte.d.ts → hierarchy/Pack.svelte.d.ts} +0 -0
  131. /package/dist/components/{Partition.svelte.d.ts → hierarchy/Partition.svelte.d.ts} +0 -0
  132. /package/dist/components/{Tree.svelte.d.ts → hierarchy/Tree.svelte.d.ts} +0 -0
  133. /package/dist/components/{Treemap.svelte.d.ts → hierarchy/Treemap.svelte.d.ts} +0 -0
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import Chart from '../components/Chart.svelte';
3
3
  import Layer from '../components/layers/Layer.svelte';
4
- import GeoPath from '../components/GeoPath.svelte';
4
+ import GeoPath from '../components/geo/GeoPath.svelte';
5
5
 
6
6
  type Props = {
7
7
  features: any[];
@@ -70,9 +70,7 @@
70
70
 
71
71
  const ctx = getChartContext();
72
72
 
73
- const isVertical = $derived(
74
- x != null || (x1Prop != null && x2Prop != null && x1Prop === x2Prop)
75
- );
73
+ const isVertical = $derived(x != null || (x1Prop != null && x2Prop != null && x1Prop === x2Prop));
76
74
 
77
75
  const line = $derived({
78
76
  x1: x1Prop != null ? ctx.xScale(x1Prop) : x != null ? ctx.xScale(x) : ctx.xRange[0],
@@ -81,7 +81,9 @@
81
81
  }
82
82
  return {
83
83
  x: x ? ctx.xScale(x) + (isScaleBand(ctx.xScale) ? ctx.xScale.bandwidth() / 2 : 0) : 0,
84
- y: y ? ctx.yScale(y) + (isScaleBand(ctx.yScale) ? ctx.yScale.bandwidth() / 2 : 0) : ctx.height,
84
+ y: y
85
+ ? ctx.yScale(y) + (isScaleBand(ctx.yScale) ? ctx.yScale.bandwidth() / 2 : 0)
86
+ : ctx.height,
85
87
  };
86
88
  });
87
89
 
@@ -116,16 +118,8 @@
116
118
  const linkEndpoints = $derived.by(() => {
117
119
  if (!link) return null;
118
120
 
119
- const dirX = labelPlacement.includes('left')
120
- ? -1
121
- : labelPlacement.includes('right')
122
- ? 1
123
- : 0;
124
- const dirY = labelPlacement.includes('top')
125
- ? -1
126
- : labelPlacement.includes('bottom')
127
- ? 1
128
- : 0;
121
+ const dirX = labelPlacement.includes('left') ? -1 : labelPlacement.includes('right') ? 1 : 0;
122
+ const dirY = labelPlacement.includes('top') ? -1 : labelPlacement.includes('bottom') ? 1 : 0;
129
123
  if (dirX === 0 && dirY === 0) return null; // labelPlacement='center' — no line
130
124
 
131
125
  const mag = Math.hypot(dirX, dirY);
@@ -30,6 +30,13 @@ function getBrushElements(container) {
30
30
  handles: container.querySelectorAll('.lc-brush-handle'),
31
31
  };
32
32
  }
33
+ // BrushContext is lazy-loaded inside Chart, so tests that enable brush must
34
+ // wait for the dynamic import to resolve before querying brush DOM.
35
+ async function awaitBrushReady(container) {
36
+ await vi.waitFor(() => {
37
+ expect(container.querySelector('.lc-brush-context')).not.toBeNull();
38
+ });
39
+ }
33
40
  describe('BrushContext', () => {
34
41
  describe('rendering', () => {
35
42
  it('should not render brush UI when brush is disabled', async () => {
@@ -46,7 +53,7 @@ describe('BrushContext', () => {
46
53
  ...defaultChartProps,
47
54
  brush: true,
48
55
  });
49
- await tick();
56
+ await awaitBrushReady(container);
50
57
  const { context } = getBrushElements(container);
51
58
  expect(context).not.toBeNull();
52
59
  });
@@ -55,7 +62,7 @@ describe('BrushContext', () => {
55
62
  ...defaultChartProps,
56
63
  brush: true,
57
64
  });
58
- await tick();
65
+ await awaitBrushReady(container);
59
66
  const { range, handles } = getBrushElements(container);
60
67
  expect(range).toBeNull();
61
68
  expect(handles.length).toBe(0);
@@ -73,7 +80,7 @@ describe('BrushContext', () => {
73
80
  chartContext = ctx;
74
81
  },
75
82
  });
76
- await vi.waitFor(() => expect(chartContext).toBeDefined());
83
+ await vi.waitFor(() => expect(chartContext?.brush).not.toBeNull());
77
84
  let { range } = getBrushElements(container);
78
85
  expect(range).toBeNull();
79
86
  chartContext.brush.move({ x: [2, 8] });
@@ -93,7 +100,7 @@ describe('BrushContext', () => {
93
100
  chartContext = ctx;
94
101
  },
95
102
  });
96
- await vi.waitFor(() => expect(chartContext).toBeDefined());
103
+ await vi.waitFor(() => expect(chartContext?.brush).not.toBeNull());
97
104
  chartContext.brush.move({ x: [2, 5] });
98
105
  await tick();
99
106
  const { range } = getBrushElements(container);
@@ -116,7 +123,7 @@ describe('BrushContext', () => {
116
123
  chartContext = ctx;
117
124
  },
118
125
  });
119
- await vi.waitFor(() => expect(chartContext).toBeDefined());
126
+ await vi.waitFor(() => expect(chartContext?.brush).not.toBeNull());
120
127
  chartContext.brush.move({ x: [2, 5] });
121
128
  await tick();
122
129
  let { range } = getBrushElements(container);
@@ -138,7 +145,7 @@ describe('BrushContext', () => {
138
145
  chartContext = ctx;
139
146
  },
140
147
  });
141
- await vi.waitFor(() => expect(chartContext).toBeDefined());
148
+ await vi.waitFor(() => expect(chartContext?.brush).not.toBeNull());
142
149
  chartContext.brush.move({ x: [2, 8] });
143
150
  await tick();
144
151
  let { range } = getBrushElements(container);
@@ -159,7 +166,7 @@ describe('BrushContext', () => {
159
166
  chartContext = ctx;
160
167
  },
161
168
  });
162
- await vi.waitFor(() => expect(chartContext).toBeDefined());
169
+ await vi.waitFor(() => expect(chartContext?.brush).not.toBeNull());
163
170
  chartContext.brush.selectAll();
164
171
  await tick();
165
172
  const { range } = getBrushElements(container);
@@ -180,7 +187,7 @@ describe('BrushContext', () => {
180
187
  chartContext = ctx;
181
188
  },
182
189
  });
183
- await vi.waitFor(() => expect(chartContext).toBeDefined());
190
+ await vi.waitFor(() => expect(chartContext?.brush).not.toBeNull());
184
191
  chartContext.brush.move({ y: [20, 80] });
185
192
  await tick();
186
193
  const { range } = getBrushElements(container);
@@ -207,7 +214,7 @@ describe('BrushContext', () => {
207
214
  chartContext = ctx;
208
215
  },
209
216
  });
210
- await vi.waitFor(() => expect(chartContext).toBeDefined());
217
+ await vi.waitFor(() => expect(chartContext?.brush).not.toBeNull());
211
218
  const brushEl = container.querySelector('.lc-brush-context');
212
219
  const rect = brushEl.getBoundingClientRect();
213
220
  // Simulate a brush drag: pointerdown → pointermove → pointerup
@@ -236,7 +243,7 @@ describe('BrushContext', () => {
236
243
  x: [3, 7],
237
244
  },
238
245
  });
239
- await tick();
246
+ await awaitBrushReady(container);
240
247
  const { range } = getBrushElements(container);
241
248
  expect(range).not.toBeNull();
242
249
  });
@@ -247,7 +254,7 @@ describe('BrushContext', () => {
247
254
  x: [0, 10],
248
255
  },
249
256
  });
250
- await tick();
257
+ await awaitBrushReady(container);
251
258
  const { range } = getBrushElements(container);
252
259
  expect(range).toBeNull();
253
260
  });
@@ -258,7 +265,7 @@ describe('BrushContext', () => {
258
265
  x: null,
259
266
  },
260
267
  });
261
- await tick();
268
+ await awaitBrushReady(container);
262
269
  const { range } = getBrushElements(container);
263
270
  expect(range).toBeNull();
264
271
  });
@@ -270,7 +277,7 @@ describe('BrushContext', () => {
270
277
  },
271
278
  });
272
279
  const { container } = render(Chart, props);
273
- await tick();
280
+ await awaitBrushReady(container);
274
281
  let { range } = getBrushElements(container);
275
282
  expect(range).not.toBeNull();
276
283
  const initialWidth = parseFloat(range.style.width);
@@ -289,7 +296,7 @@ describe('BrushContext', () => {
289
296
  },
290
297
  });
291
298
  const { container } = render(Chart, props);
292
- await tick();
299
+ await awaitBrushReady(container);
293
300
  let { range } = getBrushElements(container);
294
301
  expect(range).not.toBeNull();
295
302
  props.brush = { x: [null, null] };
@@ -19,9 +19,10 @@
19
19
  import type { GeoStateProps } from '../states/geo.svelte.js';
20
20
  import TooltipContext from './tooltip/TooltipContext.svelte';
21
21
 
22
- import { geoFitObjectTransform } from '../utils/geo.js';
23
22
  import TransformContext from './TransformContext.svelte';
24
- import BrushContext from './BrushContext.svelte';
23
+ // BrushContext (used only when `brush` prop is set) is lazy-loaded inline
24
+ // via `{#await import(...)}` so non-brush charts don't pay for it.
25
+ import type BrushContext from './BrushContext.svelte';
25
26
  import {
26
27
  type BrushDomainType,
27
28
  type BrushState,
@@ -777,18 +778,21 @@
777
778
  }
778
779
  });
779
780
 
780
- const initialTransform = $derived(
781
- transform?.mode === 'projection' &&
782
- (resolvedApply.translate || resolvedApply.scale) &&
783
- geo?.fitGeojson &&
784
- geo?.projection
785
- ? geoFitObjectTransform(
786
- geo.projection(),
787
- [chartState.width, chartState.height],
788
- geo.fitGeojson
789
- )
790
- : undefined
791
- );
781
+ const initialTransform = $derived.by(() => {
782
+ if (
783
+ transform?.mode !== 'projection' ||
784
+ !(resolvedApply.translate || resolvedApply.scale) ||
785
+ !geo?.fitGeojson ||
786
+ !geo?.projection
787
+ ) {
788
+ return undefined;
789
+ }
790
+ // Inlined to avoid pulling `$lib/utils/geo.js` (and its d3-geo imports)
791
+ // into Chart's static graph for non-geo charts.
792
+ const fitted = geo.projection().fitSize([chartState.width, chartState.height], geo.fitGeojson);
793
+ const t = fitted.translate();
794
+ return { translate: { x: t[0], y: t[1] }, scale: fitted.scale() };
795
+ });
792
796
 
793
797
  const processTranslate = $derived.by(() => {
794
798
  if (resolvedApply.rotation && chartState.geoState?.projection) {
@@ -1144,8 +1148,37 @@
1144
1148
  {onTransform}
1145
1149
  {ondragend}
1146
1150
  >
1147
- <!-- svelte-ignore ownership_invalid_binding -->
1148
- <BrushContext {...enhancedBrushProps} bind:state={chartState.brushState}>
1151
+ {#if brush}
1152
+ {#await import('./BrushContext.svelte')}
1153
+ <!--
1154
+ Pending: render the chart subtree immediately so the chart paints
1155
+ before the BrushContext chunk arrives (avoids a perceived hang on
1156
+ slow networks). The subtree re-mounts once `{:then}` resolves —
1157
+ acceptable because it happens before user interaction, brush is
1158
+ an opt-in feature, and any chart state at that point is empty.
1159
+ -->
1160
+ <!-- svelte-ignore ownership_invalid_binding -->
1161
+ <TooltipContext
1162
+ onclick={onTooltipClick}
1163
+ {...getObjectOrNull(tooltipContext)}
1164
+ bind:state={chartState.tooltipState}
1165
+ >
1166
+ <ChartChildren {children} {tooltipContext} {...restProps} />
1167
+ </TooltipContext>
1168
+ {:then { default: BrushContext }}
1169
+ <!-- svelte-ignore ownership_invalid_binding -->
1170
+ <BrushContext {...enhancedBrushProps} bind:state={chartState.brushState}>
1171
+ <!-- svelte-ignore ownership_invalid_binding -->
1172
+ <TooltipContext
1173
+ onclick={onTooltipClick}
1174
+ {...getObjectOrNull(tooltipContext)}
1175
+ bind:state={chartState.tooltipState}
1176
+ >
1177
+ <ChartChildren {children} {tooltipContext} {...restProps} />
1178
+ </TooltipContext>
1179
+ </BrushContext>
1180
+ {/await}
1181
+ {:else}
1149
1182
  <!-- svelte-ignore ownership_invalid_binding -->
1150
1183
  <TooltipContext
1151
1184
  onclick={onTooltipClick}
@@ -1154,7 +1187,7 @@
1154
1187
  >
1155
1188
  <ChartChildren {children} {tooltipContext} {...restProps} />
1156
1189
  </TooltipContext>
1157
- </BrushContext>
1190
+ {/if}
1158
1191
  </TransformContext>
1159
1192
  {/key}
1160
1193
  </div>
@@ -10,7 +10,7 @@ import type { BaseRange, Nice, PaddingArray, Without, XRangeWithScale, YRangeWit
10
10
  import type { GeoStateProps } from '../states/geo.svelte.js';
11
11
  import TooltipContext from './tooltip/TooltipContext.svelte';
12
12
  import TransformContext from './TransformContext.svelte';
13
- import BrushContext from './BrushContext.svelte';
13
+ import type BrushContext from './BrushContext.svelte';
14
14
  import { ChartState } from '../states/chart.svelte.js';
15
15
  import type { StackLayout } from '../states/series.svelte.js';
16
16
  import type { ChartChildrenProps } from './ChartChildren.svelte';
@@ -1,6 +1,6 @@
1
1
  <script lang="ts" module>
2
2
  import type { ComponentProps, Snippet } from 'svelte';
3
- import TooltipContext from './tooltip/TooltipContext.svelte';
3
+ import type TooltipContext from './tooltip/TooltipContext.svelte';
4
4
  import type Tooltip from './tooltip/Tooltip.svelte';
5
5
  import type TooltipHeader from './tooltip/TooltipHeader.svelte';
6
6
  import type TooltipList from './tooltip/TooltipList.svelte';
@@ -133,27 +133,37 @@
133
133
  import { asAny } from '../utils/types.js';
134
134
  import { getObjectOrNull } from '../utils/common.js';
135
135
 
136
- import Area from './Area.svelte';
137
- import Arc from './Arc.svelte';
136
+ import type Area from './Area.svelte';
137
+ import type Arc from './Arc.svelte';
138
138
  import Axis from './Axis.svelte';
139
- import Bars from './Bars.svelte';
140
- import BrushContext from './BrushContext.svelte';
141
- import ChartAnnotations from './charts/ChartAnnotations.svelte';
139
+ import type Bars from './Bars.svelte';
140
+ import type BrushContext from './BrushContext.svelte';
142
141
  import ChartClipPath from './ChartClipPath.svelte';
143
- import DefaultTooltip from './charts/DefaultTooltip.svelte';
142
+ // DefaultTooltip is lazy-loaded inline (only when `tooltipContext` is set
143
+ // and no custom `tooltip` snippet is provided).
144
+ import type DefaultTooltip from './charts/DefaultTooltip.svelte';
144
145
  import Grid from './Grid.svelte';
145
- import Group from './Group.svelte';
146
+ import type Group from './Group.svelte';
146
147
  import Highlight from './Highlight.svelte';
147
- import Points from './Points.svelte';
148
- import Labels from './Labels.svelte';
149
- import Legend from './Legend.svelte';
150
- import Line from './Line.svelte';
151
- import Pie from './Pie.svelte';
148
+ import type Line from './Line.svelte';
149
+ import type Pie from './Pie.svelte';
152
150
  import Rule from './Rule.svelte';
153
- import Spline from './Spline.svelte';
151
+ import type Spline from './Spline.svelte';
154
152
  import type { Canvas, Svg } from './index.js';
155
153
  import type { ChartAnnotations as ChartAnnotationsType } from './charts/types.js';
156
154
 
155
+ // ChartAnnotations, Labels, Legend, and Points are dynamically imported
156
+ // inline in the markup via `{#await import(...)}` so composed
157
+ // `<Chart><Svg>...</Svg></Chart>` users (no auto-render props) don't pay
158
+ // for them. The bundler turns each `import()` into a separate chunk. The
159
+ // type-only imports below keep `ComponentProps<typeof X>` working in the
160
+ // `props` prop type definition.
161
+ // Note: lazy-only deps must be added to `vite.config.js`'s `optimizeDeps.include`
162
+ // (e.g. `d3-interpolate` from Legend) so Vite doesn't reload mid-test in CI.
163
+ import type Labels from './Labels.svelte';
164
+ import type Legend from './Legend.svelte';
165
+ import type Points from './Points.svelte';
166
+
157
167
  const context = getChartContext<TData, XScale, YScale>();
158
168
  const settings = getSettings();
159
169
 
@@ -204,7 +214,11 @@
204
214
  {/if}
205
215
 
206
216
  <ChartClipPath disabled={!context.props.brush && context.transformState?.mode !== 'domain'}>
207
- <ChartAnnotations {annotations} layer="below" />
217
+ {#if annotations.length > 0}
218
+ {#await import('./charts/ChartAnnotations.svelte') then { default: ChartAnnotations }}
219
+ <ChartAnnotations {annotations} layer="below" />
220
+ {/await}
221
+ {/if}
208
222
 
209
223
  {@render belowMarks?.(snippetProps)}
210
224
  {@render marks?.(snippetProps)}
@@ -263,23 +277,27 @@
263
277
  {#if typeof points === 'function'}
264
278
  {@render points(snippetProps)}
265
279
  {:else if points}
266
- {#each context.series.visibleSeries as s, i (s.key)}
267
- <Points
268
- seriesKey={s.key}
269
- stroke="var(--color-surface-100, light-dark(white, black))"
270
- {...getObjectOrNull(points)}
271
- {...props.points}
272
- />
273
- {/each}
280
+ {#await import('./Points.svelte') then { default: Points }}
281
+ {#each context.series.visibleSeries as s, i (s.key)}
282
+ <Points
283
+ seriesKey={s.key}
284
+ stroke="var(--color-surface-100, light-dark(white, black))"
285
+ {...getObjectOrNull(points)}
286
+ {...props.points}
287
+ />
288
+ {/each}
289
+ {/await}
274
290
  {/if}
275
291
 
276
292
  {#if typeof labels === 'function'}
277
293
  {@render labels(snippetProps)}
278
294
  {:else if labels}
279
- {@const labelSeriesKey = typeof labels === 'object' ? labels.seriesKey : undefined}
280
- {#each context.series.visibleSeries.filter((s) => !labelSeriesKey || s.key === labelSeriesKey) as s, i (s.key)}
281
- <Labels seriesKey={s.key} {...getObjectOrNull(labels)} {...props.labels} />
282
- {/each}
295
+ {#await import('./Labels.svelte') then { default: Labels }}
296
+ {@const labelSeriesKey = typeof labels === 'object' ? labels.seriesKey : undefined}
297
+ {#each context.series.visibleSeries.filter((s) => !labelSeriesKey || s.key === labelSeriesKey) as s, i (s.key)}
298
+ <Labels seriesKey={s.key} {...getObjectOrNull(labels)} {...props.labels} />
299
+ {/each}
300
+ {/await}
283
301
  {/if}
284
302
 
285
303
  {#if typeof highlight === 'function'}
@@ -288,7 +306,11 @@
288
306
  <Highlight {...typeof highlight === 'object' ? highlight : {}} {...props.highlight} />
289
307
  {/if}
290
308
 
291
- <ChartAnnotations {annotations} layer="above" />
309
+ {#if annotations.length > 0}
310
+ {#await import('./charts/ChartAnnotations.svelte') then { default: ChartAnnotations }}
311
+ <ChartAnnotations {annotations} layer="above" />
312
+ {/await}
313
+ {/if}
292
314
  </ChartClipPath>
293
315
  </Layer>
294
316
 
@@ -297,12 +319,16 @@
297
319
  {#if typeof legend === 'function'}
298
320
  {@render legend(snippetProps)}
299
321
  {:else if legend}
300
- <Legend placement="bottom" {...getObjectOrNull(legend)} {...props.legend} />
322
+ {#await import('./Legend.svelte') then { default: Legend }}
323
+ <Legend placement="bottom" {...getObjectOrNull(legend)} {...props.legend} />
324
+ {/await}
301
325
  {/if}
302
326
 
303
327
  {#if typeof tooltip === 'function'}
304
328
  {@render tooltip(snippetProps)}
305
329
  {:else if tooltipContext}
306
- <DefaultTooltip tooltipProps={props.tooltip} canHaveTotal />
330
+ {#await import('./charts/DefaultTooltip.svelte') then { default: DefaultTooltip }}
331
+ <DefaultTooltip tooltipProps={props.tooltip} canHaveTotal />
332
+ {/await}
307
333
  {/if}
308
334
  {/if}
@@ -1,5 +1,5 @@
1
1
  import type { ComponentProps, Snippet } from 'svelte';
2
- import TooltipContext from './tooltip/TooltipContext.svelte';
2
+ import type TooltipContext from './tooltip/TooltipContext.svelte';
3
3
  import type Tooltip from './tooltip/Tooltip.svelte';
4
4
  import type TooltipHeader from './tooltip/TooltipHeader.svelte';
5
5
  import type TooltipList from './tooltip/TooltipList.svelte';
@@ -104,23 +104,23 @@ export type ChartChildrenProps<TData, XScale extends AnyScale = AnyScale, YScale
104
104
  };
105
105
  import { type ChartState } from '../contexts/chart.js';
106
106
  import type { AnyScale } from '../utils/scales.svelte.js';
107
- import Area from './Area.svelte';
108
- import Arc from './Arc.svelte';
107
+ import type Area from './Area.svelte';
108
+ import type Arc from './Arc.svelte';
109
109
  import Axis from './Axis.svelte';
110
- import Bars from './Bars.svelte';
111
- import BrushContext from './BrushContext.svelte';
110
+ import type Bars from './Bars.svelte';
111
+ import type BrushContext from './BrushContext.svelte';
112
112
  import Grid from './Grid.svelte';
113
- import Group from './Group.svelte';
113
+ import type Group from './Group.svelte';
114
114
  import Highlight from './Highlight.svelte';
115
- import Points from './Points.svelte';
116
- import Labels from './Labels.svelte';
117
- import Legend from './Legend.svelte';
118
- import Line from './Line.svelte';
119
- import Pie from './Pie.svelte';
115
+ import type Line from './Line.svelte';
116
+ import type Pie from './Pie.svelte';
120
117
  import Rule from './Rule.svelte';
121
- import Spline from './Spline.svelte';
118
+ import type Spline from './Spline.svelte';
122
119
  import type { Canvas, Svg } from './index.js';
123
120
  import type { ChartAnnotations as ChartAnnotationsType } from './charts/types.js';
121
+ import type Labels from './Labels.svelte';
122
+ import type Legend from './Legend.svelte';
123
+ import type Points from './Points.svelte';
124
124
  declare function $$render<TData = any, XScale extends AnyScale = AnyScale, YScale extends AnyScale = AnyScale>(): {
125
125
  props: ChartChildrenProps<TData, XScale, YScale>;
126
126
  exports: {};
@@ -11,7 +11,7 @@
11
11
  </script>
12
12
 
13
13
  <script lang="ts">
14
- import { computedStyles } from '@layerstack/svelte-actions';
14
+ import { computedStyles } from '@layerstack/svelte-actions/styles';
15
15
  import { cls } from '@layerstack/tailwind';
16
16
 
17
17
  let { class: className, children }: ComputedStylesProps = $props();
@@ -113,7 +113,8 @@
113
113
  import Group, { type GroupProps } from './Group.svelte';
114
114
  import Line from './Line.svelte';
115
115
  import Rule from './Rule.svelte';
116
- import Spline from './Spline.svelte';
116
+ // Spline (used only for radial linear grid lines) is lazy-loaded inline
117
+ // via `{#await import(...)}` so non-radial grids don't pay for it.
117
118
  import { getChartContext } from '../contexts/chart.js';
118
119
  import { extractLayerProps } from '../utils/attributes.js';
119
120
  import { autoTickVals, type TicksConfig } from '../utils/ticks.js';
@@ -232,16 +233,18 @@
232
233
  class={cls('lc-grid-y-radial-circle', classes.line, splineProps?.class)}
233
234
  />
234
235
  {:else}
235
- <Spline
236
- data={xTickVals.map((x) => ({ x, y }))}
237
- x="x"
238
- y="y"
239
- {stroke}
240
- motion={tweenConfig}
241
- curve={curveLinearClosed}
242
- {...splineProps}
243
- class={cls('lc-grid-y-radial-line', classes.line, splineProps?.class)}
244
- />
236
+ {#await import('./Spline.svelte') then { default: Spline }}
237
+ <Spline
238
+ data={xTickVals.map((x) => ({ x, y }))}
239
+ x="x"
240
+ y="y"
241
+ {stroke}
242
+ motion={tweenConfig}
243
+ curve={curveLinearClosed}
244
+ {...splineProps}
245
+ class={cls('lc-grid-y-radial-line', classes.line, splineProps?.class)}
246
+ />
247
+ {/await}
245
248
  {/if}
246
249
  {:else}
247
250
  <Line
@@ -2,7 +2,7 @@
2
2
  import type { ComponentProps, Snippet } from 'svelte';
3
3
  import Circle from './Circle.svelte';
4
4
  import Line from './Line.svelte';
5
- import Bar from './Bar.svelte';
5
+ import type Bar from './Bar.svelte';
6
6
  import Rect from './Rect.svelte';
7
7
  import { accessor, type Accessor } from '../utils/common.js';
8
8
 
@@ -660,13 +660,15 @@
660
660
  {#if typeof bar === 'function'}
661
661
  {@render bar()}
662
662
  {:else}
663
- <Bar
664
- motion={motion === 'spring' ? 'spring' : undefined}
665
- data={highlightData}
666
- {opacity}
667
- {...extractLayerProps(bar, 'lc-highlight-bar')}
668
- onclick={onBarClick && ((e) => onBarClick(e, { data: highlightData }))}
669
- />
663
+ {#await import('./Bar.svelte') then { default: Bar }}
664
+ <Bar
665
+ motion={motion === 'spring' ? 'spring' : undefined}
666
+ data={highlightData}
667
+ {opacity}
668
+ {...extractLayerProps(bar, 'lc-highlight-bar')}
669
+ onclick={onBarClick && ((e) => onBarClick(e, { data: highlightData }))}
670
+ />
671
+ {/await}
670
672
  {/if}
671
673
  {/if}
672
674
 
@@ -1,7 +1,7 @@
1
1
  import type { ComponentProps, Snippet } from 'svelte';
2
2
  import Circle from './Circle.svelte';
3
3
  import Line from './Line.svelte';
4
- import Bar from './Bar.svelte';
4
+ import type Bar from './Bar.svelte';
5
5
  import Rect from './Rect.svelte';
6
6
  import { type Accessor } from '../utils/common.js';
7
7
  export type HighlightPointData = {
@@ -60,7 +60,7 @@
60
60
  import { curveLinearClosed } from 'd3-shape';
61
61
  import { cls } from '@layerstack/tailwind';
62
62
 
63
- import GeoPath from './GeoPath.svelte';
63
+ import GeoPath from './geo/GeoPath.svelte';
64
64
  import Group, { type GroupProps } from './Group.svelte';
65
65
  import Spline from './Spline.svelte';
66
66
  import { getChartContext } from '../contexts/chart.js';
@@ -187,7 +187,10 @@
187
187
 
188
188
  // Array/data mode: any of x1/y1/x2/y2 is a string or function
189
189
  const isArrayMode = $derived(
190
- isAccessorAccessor(x1) || isAccessorAccessor(y1) || isAccessorAccessor(x2) || isAccessorAccessor(y2)
190
+ isAccessorAccessor(x1) ||
191
+ isAccessorAccessor(y1) ||
192
+ isAccessorAccessor(x2) ||
193
+ isAccessorAccessor(y2)
191
194
  );
192
195
 
193
196
  // Pixel mode: any of x1/y1/x2/y2 is a number (and not array mode)
@@ -320,7 +323,7 @@
320
323
  );
321
324
 
322
325
  // --- Array mode paths ---
323
- const arrayRows = $derived(isArrayMode ? ((data ?? ctx.data) ?? []) : []);
326
+ const arrayRows = $derived(isArrayMode ? (data ?? ctx.data ?? []) : []);
324
327
 
325
328
  function resolvePerDatum<T>(value: T | ((d: any) => T) | undefined, d: any): T | undefined {
326
329
  return typeof value === 'function' ? (value as (d: any) => T)(d) : (value as T | undefined);
@@ -334,7 +337,9 @@
334
337
  // each per row in array mode (e.g. stroke={(d) => colorScale(...)})
335
338
  const strokeProp = $derived((restProps as any).stroke);
336
339
  const fillProp = $derived((restProps as any).fill);
337
- const strokeWidthProp = $derived((restProps as any)['stroke-width'] ?? (restProps as any).strokeWidth);
340
+ const strokeWidthProp = $derived(
341
+ (restProps as any)['stroke-width'] ?? (restProps as any).strokeWidth
342
+ );
338
343
  </script>
339
344
 
340
345
  {#if isArrayMode}
@@ -17,6 +17,6 @@ type TransformContextPropsWithoutHTML = TransformStateOptions & {
17
17
  type TransformContextProps = TransformContextPropsWithoutHTML & Without<HTMLAttributes<HTMLElement>, TransformContextPropsWithoutHTML>;
18
18
  import type { Snippet } from 'svelte';
19
19
  import type { Without } from '../utils/types.js';
20
- declare const TransformContext: import("svelte").Component<TransformContextProps, {}, "ref" | "state">;
20
+ declare const TransformContext: import("svelte").Component<TransformContextProps, {}, "state" | "ref">;
21
21
  type TransformContext = ReturnType<typeof TransformContext>;
22
22
  export default TransformContext;
@@ -75,7 +75,7 @@
75
75
  import { pointRadial } from 'd3-shape';
76
76
  import { cls } from '@layerstack/tailwind';
77
77
 
78
- import GeoPath from './GeoPath.svelte';
78
+ import GeoPath from './geo/GeoPath.svelte';
79
79
  import Group, { type GroupProps } from './Group.svelte';
80
80
  import Path from './Path.svelte';
81
81
  import { getChartContext } from '../contexts/chart.js';