layerchart 2.0.0-next.1 → 2.0.0-next.3

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 (266) hide show
  1. package/dist/actions/movable.d.ts +28 -0
  2. package/dist/actions/movable.js +91 -0
  3. package/dist/components/AnnotationLine.svelte +143 -0
  4. package/dist/components/AnnotationLine.svelte.d.ts +30 -0
  5. package/dist/components/AnnotationPoint.svelte +119 -0
  6. package/dist/components/AnnotationPoint.svelte.d.ts +34 -0
  7. package/dist/components/AnnotationRange.svelte +147 -0
  8. package/dist/components/AnnotationRange.svelte.d.ts +40 -0
  9. package/dist/components/Arc.svelte +344 -151
  10. package/dist/components/Arc.svelte.d.ts +138 -0
  11. package/dist/components/Area.svelte +165 -149
  12. package/dist/components/Area.svelte.d.ts +45 -0
  13. package/dist/components/Axis.svelte +283 -180
  14. package/dist/components/Axis.svelte.d.ts +117 -0
  15. package/dist/components/Bar.svelte +166 -107
  16. package/dist/components/Bar.svelte.d.ts +51 -0
  17. package/dist/components/Bars.svelte +56 -67
  18. package/dist/components/Bars.svelte.d.ts +27 -0
  19. package/dist/components/Blur.svelte +42 -12
  20. package/dist/components/Blur.svelte.d.ts +23 -21
  21. package/dist/components/Bounds.svelte +49 -19
  22. package/dist/components/Bounds.svelte.d.ts +24 -50
  23. package/dist/components/BrushContext.svelte +296 -168
  24. package/dist/components/BrushContext.svelte.d.ts +97 -65
  25. package/dist/components/Calendar.svelte +116 -59
  26. package/dist/components/Calendar.svelte.d.ts +50 -31
  27. package/dist/components/Chart.svelte +1289 -398
  28. package/dist/components/Chart.svelte.d.ts +535 -410
  29. package/dist/components/ChartClipPath.svelte +37 -15
  30. package/dist/components/ChartClipPath.svelte.d.ts +21 -19
  31. package/dist/components/Circle.svelte +124 -85
  32. package/dist/components/Circle.svelte.d.ts +52 -0
  33. package/dist/components/CircleClipPath.svelte +76 -16
  34. package/dist/components/CircleClipPath.svelte.d.ts +46 -0
  35. package/dist/components/ClipPath.svelte +71 -21
  36. package/dist/components/ClipPath.svelte.d.ts +40 -27
  37. package/dist/components/ColorRamp.svelte +75 -9
  38. package/dist/components/ColorRamp.svelte.d.ts +37 -19
  39. package/dist/components/ComputedStyles.svelte +17 -5
  40. package/dist/components/ComputedStyles.svelte.d.ts +11 -19
  41. package/dist/components/Connector.svelte +149 -0
  42. package/dist/components/Connector.svelte.d.ts +51 -0
  43. package/dist/components/Dagre.svelte +211 -122
  44. package/dist/components/Dagre.svelte.d.ts +119 -56
  45. package/dist/components/ForceSimulation.svelte +215 -90
  46. package/dist/components/ForceSimulation.svelte.d.ts +82 -35
  47. package/dist/components/Frame.svelte +33 -13
  48. package/dist/components/Frame.svelte.d.ts +13 -17
  49. package/dist/components/GeoCircle.svelte +29 -16
  50. package/dist/components/GeoCircle.svelte.d.ts +22 -24
  51. package/dist/components/GeoContext.svelte +113 -72
  52. package/dist/components/GeoContext.svelte.d.ts +49 -41
  53. package/dist/components/GeoEdgeFade.svelte +49 -13
  54. package/dist/components/GeoEdgeFade.svelte.d.ts +17 -19
  55. package/dist/components/GeoPath.svelte +157 -127
  56. package/dist/components/GeoPath.svelte.d.ts +48 -36
  57. package/dist/components/GeoPoint.svelte +52 -20
  58. package/dist/components/GeoPoint.svelte.d.ts +25 -22
  59. package/dist/components/GeoSpline.svelte +75 -26
  60. package/dist/components/GeoSpline.svelte.d.ts +29 -20
  61. package/dist/components/GeoTile.svelte +100 -49
  62. package/dist/components/GeoTile.svelte.d.ts +38 -23
  63. package/dist/components/GeoVisible.svelte +17 -9
  64. package/dist/components/GeoVisible.svelte.d.ts +10 -18
  65. package/dist/components/Graticule.svelte +30 -14
  66. package/dist/components/Graticule.svelte.d.ts +11 -52
  67. package/dist/components/Grid.svelte +230 -117
  68. package/dist/components/Grid.svelte.d.ts +71 -0
  69. package/dist/components/Group.svelte +173 -106
  70. package/dist/components/Group.svelte.d.ts +81 -0
  71. package/dist/components/Highlight.svelte +410 -308
  72. package/dist/components/Highlight.svelte.d.ts +107 -0
  73. package/dist/components/Hull.svelte +97 -46
  74. package/dist/components/Hull.svelte.d.ts +40 -30
  75. package/dist/components/Labels.svelte +127 -47
  76. package/dist/components/Labels.svelte.d.ts +70 -27
  77. package/dist/components/Legend.svelte +374 -190
  78. package/dist/components/Legend.svelte.d.ts +95 -44
  79. package/dist/components/Line.svelte +163 -125
  80. package/dist/components/Line.svelte.d.ts +75 -0
  81. package/dist/components/LinearGradient.svelte +153 -78
  82. package/dist/components/LinearGradient.svelte.d.ts +66 -31
  83. package/dist/components/Link.svelte +160 -104
  84. package/dist/components/Link.svelte.d.ts +54 -0
  85. package/dist/components/Marker.svelte +100 -39
  86. package/dist/components/Marker.svelte.d.ts +59 -27
  87. package/dist/components/MarkerWrapper.svelte +35 -0
  88. package/dist/components/MarkerWrapper.svelte.d.ts +18 -0
  89. package/dist/components/MonthPath.svelte +65 -20
  90. package/dist/components/MonthPath.svelte.d.ts +23 -17
  91. package/dist/components/MotionPath.svelte +80 -24
  92. package/dist/components/MotionPath.svelte.d.ts +46 -27
  93. package/dist/components/Pack.svelte +53 -17
  94. package/dist/components/Pack.svelte.d.ts +42 -21
  95. package/dist/components/Partition.svelte +64 -22
  96. package/dist/components/Partition.svelte.d.ts +49 -26
  97. package/dist/components/Pattern.svelte +297 -11
  98. package/dist/components/Pattern.svelte.d.ts +103 -19
  99. package/dist/components/Pie.svelte +122 -76
  100. package/dist/components/Pie.svelte.d.ts +65 -51
  101. package/dist/components/Point.svelte +20 -9
  102. package/dist/components/Point.svelte.d.ts +16 -20
  103. package/dist/components/Points.svelte +148 -137
  104. package/dist/components/Points.svelte.d.ts +45 -34
  105. package/dist/components/RadialGradient.svelte +143 -70
  106. package/dist/components/RadialGradient.svelte.d.ts +69 -31
  107. package/dist/components/Rect.svelte +121 -102
  108. package/dist/components/Rect.svelte.d.ts +36 -0
  109. package/dist/components/RectClipPath.svelte +82 -18
  110. package/dist/components/RectClipPath.svelte.d.ts +55 -0
  111. package/dist/components/Rule.svelte +107 -63
  112. package/dist/components/Rule.svelte.d.ts +40 -19
  113. package/dist/components/Sankey.svelte +132 -55
  114. package/dist/components/Sankey.svelte.d.ts +61 -31
  115. package/dist/components/Spline.svelte +281 -218
  116. package/dist/components/Spline.svelte.d.ts +95 -0
  117. package/dist/components/Text.svelte +437 -176
  118. package/dist/components/Text.svelte.d.ts +130 -0
  119. package/dist/components/Threshold.svelte +48 -16
  120. package/dist/components/Threshold.svelte.d.ts +29 -31
  121. package/dist/components/TileImage.svelte +103 -30
  122. package/dist/components/TileImage.svelte.d.ts +48 -23
  123. package/dist/components/TransformContext.svelte +365 -171
  124. package/dist/components/TransformControls.svelte +50 -26
  125. package/dist/components/TransformControls.svelte.d.ts +27 -19
  126. package/dist/components/Tree.svelte +74 -33
  127. package/dist/components/Tree.svelte.d.ts +42 -30
  128. package/dist/components/Treemap.svelte +119 -42
  129. package/dist/components/Treemap.svelte.d.ts +75 -27
  130. package/dist/components/Voronoi.svelte +108 -76
  131. package/dist/components/Voronoi.svelte.d.ts +40 -41
  132. package/dist/components/charts/ArcChart.svelte +464 -0
  133. package/dist/components/charts/ArcChart.svelte.d.ts +90 -0
  134. package/dist/components/charts/AreaChart.svelte +450 -393
  135. package/dist/components/charts/AreaChart.svelte.d.ts +61 -0
  136. package/dist/components/charts/BarChart.svelte +454 -389
  137. package/dist/components/charts/BarChart.svelte.d.ts +76 -0
  138. package/dist/components/charts/ChartAnnotations.svelte +37 -0
  139. package/dist/components/charts/ChartAnnotations.svelte.d.ts +10 -0
  140. package/dist/components/charts/DefaultTooltip.svelte +60 -0
  141. package/dist/components/charts/DefaultTooltip.svelte.d.ts +10 -0
  142. package/dist/components/charts/LineChart.svelte +369 -314
  143. package/dist/components/charts/LineChart.svelte.d.ts +53 -0
  144. package/dist/components/charts/PieChart.svelte +458 -316
  145. package/dist/components/charts/PieChart.svelte.d.ts +137 -353
  146. package/dist/components/charts/ScatterChart.svelte +334 -296
  147. package/dist/components/charts/ScatterChart.svelte.d.ts +39 -0
  148. package/dist/components/charts/index.d.ts +8 -0
  149. package/dist/components/charts/index.js +7 -0
  150. package/dist/components/charts/types.d.ts +253 -0
  151. package/dist/components/charts/utils.svelte.d.ts +30 -0
  152. package/dist/components/charts/utils.svelte.js +55 -0
  153. package/dist/components/index.d.ts +76 -4
  154. package/dist/components/index.js +76 -5
  155. package/dist/components/layout/Canvas.svelte +321 -155
  156. package/dist/components/layout/Canvas.svelte.d.ts +104 -55
  157. package/dist/components/layout/Html.svelte +82 -42
  158. package/dist/components/layout/Html.svelte.d.ts +39 -28
  159. package/dist/components/layout/Layer.svelte +39 -0
  160. package/dist/components/layout/Layer.svelte.d.ts +17 -0
  161. package/dist/components/layout/Svg.svelte +122 -70
  162. package/dist/components/layout/Svg.svelte.d.ts +53 -34
  163. package/dist/components/layout/WebGL.svelte +135 -0
  164. package/dist/components/layout/WebGL.svelte.d.ts +50 -0
  165. package/dist/components/tooltip/Tooltip.svelte +246 -78
  166. package/dist/components/tooltip/Tooltip.svelte.d.ts +149 -31
  167. package/dist/components/tooltip/TooltipContext.svelte +409 -271
  168. package/dist/components/tooltip/TooltipContext.svelte.d.ts +86 -55
  169. package/dist/components/tooltip/TooltipHeader.svelte +100 -11
  170. package/dist/components/tooltip/TooltipHeader.svelte.d.ts +43 -23
  171. package/dist/components/tooltip/TooltipItem.svelte +167 -27
  172. package/dist/components/tooltip/TooltipItem.svelte.d.ts +63 -31
  173. package/dist/components/tooltip/TooltipList.svelte +22 -3
  174. package/dist/components/tooltip/TooltipList.svelte.d.ts +6 -17
  175. package/dist/components/tooltip/TooltipSeparator.svelte +27 -1
  176. package/dist/components/tooltip/TooltipSeparator.svelte.d.ts +6 -15
  177. package/dist/components/tooltip/index.d.ts +6 -0
  178. package/dist/components/tooltip/index.js +6 -0
  179. package/dist/components/tooltip/tooltipMetaContext.d.ts +79 -0
  180. package/dist/components/tooltip/tooltipMetaContext.js +139 -0
  181. package/dist/components/types.d.ts +1 -0
  182. package/dist/components/types.js +1 -0
  183. package/dist/docs/Blockquote.svelte.d.ts +18 -14
  184. package/dist/docs/Code.svelte.d.ts +26 -22
  185. package/dist/docs/ConnectorSweepMenuField.svelte +17 -0
  186. package/dist/docs/ConnectorSweepMenuField.svelte.d.ts +7 -0
  187. package/dist/docs/ConnectorTypeMenuField.svelte +17 -0
  188. package/dist/docs/ConnectorTypeMenuField.svelte.d.ts +7 -0
  189. package/dist/docs/CurveMenuField.svelte +14 -3
  190. package/dist/docs/CurveMenuField.svelte.d.ts +9 -18
  191. package/dist/docs/GeoDebug.svelte +47 -42
  192. package/dist/docs/GeoDebug.svelte.d.ts +4 -16
  193. package/dist/docs/Header1.svelte.d.ts +27 -16
  194. package/dist/docs/Json.svelte.d.ts +20 -16
  195. package/dist/docs/Layout.svelte.d.ts +18 -13
  196. package/dist/docs/Link.svelte.d.ts +33 -21
  197. package/dist/docs/PathDataMenuField.svelte +14 -10
  198. package/dist/docs/PathDataMenuField.svelte.d.ts +8 -18
  199. package/dist/docs/Preview.svelte +20 -7
  200. package/dist/docs/Preview.svelte.d.ts +12 -22
  201. package/dist/docs/TilesetField.svelte.d.ts +21 -17
  202. package/dist/docs/TransformDebug.svelte +5 -6
  203. package/dist/docs/TransformDebug.svelte.d.ts +18 -14
  204. package/dist/docs/ViewSourceButton.svelte.d.ts +21 -17
  205. package/dist/types/d3-shape-extentions.d.ts +7 -0
  206. package/dist/utils/afterTick.d.ts +5 -0
  207. package/dist/utils/afterTick.js +8 -0
  208. package/dist/utils/arcText.svelte.d.ts +57 -0
  209. package/dist/utils/arcText.svelte.js +262 -0
  210. package/dist/utils/array.d.ts +9 -1
  211. package/dist/utils/array.js +13 -0
  212. package/dist/utils/attributes.d.ts +29 -0
  213. package/dist/utils/attributes.js +40 -0
  214. package/dist/utils/canvas.js +47 -10
  215. package/dist/utils/chart.d.ts +78 -0
  216. package/dist/utils/chart.js +512 -0
  217. package/dist/utils/color.d.ts +1 -0
  218. package/dist/utils/color.js +8 -0
  219. package/dist/utils/common.d.ts +3 -5
  220. package/dist/utils/common.js +3 -2
  221. package/dist/utils/connectorUtils.d.ts +21 -0
  222. package/dist/utils/connectorUtils.js +111 -0
  223. package/dist/utils/createId.d.ts +7 -0
  224. package/dist/utils/createId.js +9 -0
  225. package/dist/utils/debug.d.ts +1 -0
  226. package/dist/utils/debug.js +84 -0
  227. package/dist/utils/filterObject.d.ts +9 -0
  228. package/dist/utils/filterObject.js +12 -0
  229. package/dist/utils/graph/dagre.d.ts +34 -0
  230. package/dist/utils/graph/dagre.js +78 -0
  231. package/dist/utils/graph/dagre.test.d.ts +1 -0
  232. package/dist/utils/{graph.test.js → graph/dagre.test.js} +19 -33
  233. package/dist/utils/graph/sankey.d.ts +28 -0
  234. package/dist/utils/{graph.js → graph/sankey.js} +13 -41
  235. package/dist/utils/index.d.ts +3 -1
  236. package/dist/utils/index.js +3 -1
  237. package/dist/utils/key.svelte.d.ts +3 -0
  238. package/dist/utils/key.svelte.js +11 -0
  239. package/dist/utils/legendPayload.d.ts +7 -0
  240. package/dist/utils/legendPayload.js +8 -0
  241. package/dist/utils/motion.svelte.d.ts +140 -0
  242. package/dist/utils/motion.svelte.js +180 -0
  243. package/dist/utils/motion.test.d.ts +1 -0
  244. package/dist/utils/motion.test.js +213 -0
  245. package/dist/utils/{rect.d.ts → rect.svelte.d.ts} +7 -4
  246. package/dist/utils/rect.svelte.js +105 -0
  247. package/dist/utils/scales.svelte.d.ts +90 -0
  248. package/dist/utils/{scales.js → scales.svelte.js} +100 -39
  249. package/dist/utils/stack.d.ts +2 -3
  250. package/dist/utils/stack.js +1 -1
  251. package/dist/utils/string.js +87 -0
  252. package/dist/utils/ticks.d.ts +8 -2
  253. package/dist/utils/ticks.js +28 -0
  254. package/dist/utils/ticks.test.d.ts +1 -0
  255. package/dist/utils/ticks.test.js +67 -0
  256. package/dist/utils/types.d.ts +81 -0
  257. package/package.json +21 -19
  258. package/dist/components/ChartContext.svelte +0 -295
  259. package/dist/components/ChartContext.svelte.d.ts +0 -139
  260. package/dist/components/TransformContext.svelte.d.ts +0 -158
  261. package/dist/stores/motionStore.d.ts +0 -30
  262. package/dist/stores/motionStore.js +0 -62
  263. package/dist/utils/graph.d.ts +0 -37
  264. package/dist/utils/rect.js +0 -107
  265. package/dist/utils/scales.d.ts +0 -66
  266. /package/dist/{utils/graph.test.d.ts → components/charts/types.js} +0 -0
@@ -1,126 +1,326 @@
1
- <script lang="ts" context="module">
2
- import { getContext, setContext } from 'svelte';
3
- import { writable, type Readable, type Writable, derived } from 'svelte/store';
1
+ <script lang="ts" module>
2
+ import type { HTMLAttributes } from 'svelte/elements';
4
3
 
5
- export const transformContextKey = Symbol();
4
+ const DEFAULT_TRANSLATE = { x: 0, y: 0 };
5
+ const DEFAULT_SCALE = 1;
6
6
 
7
7
  type TransformMode = 'canvas' | 'manual' | 'none';
8
8
  type TransformScrollMode = 'scale' | 'translate' | 'none';
9
9
 
10
10
  export type TransformContextValue = {
11
+ /**
12
+ * The current transform mode.
13
+ *
14
+ * - `canvas`: The transform is applied to the canvas element.
15
+ * - `manual`: The transform is applied manually.
16
+ * - `none`: No transform is applied.
17
+ */
11
18
  mode: TransformMode;
12
- scale: Writable<number>;
13
- setScale(value: number, options?: MotionOptions): void;
14
- translate: Writable<{ x: number; y: number }>;
15
- setTranslate(point: { x: number; y: number }, options?: MotionOptions): void;
16
- moving: Readable<boolean>;
17
- dragging: Readable<boolean>;
18
- scrollMode: Readable<TransformScrollMode>;
19
+
20
+ /**
21
+ * The current scale of the transform.
22
+ */
23
+ scale: number;
24
+
25
+ /**
26
+ * Set the scale of the transform
27
+ * @param value - the scale value to set
28
+ * @param options - motion options to apply to the transform (defaults to the motion options passed to the component)
29
+ */
30
+ setScale(value: number, options?: MotionProp): void;
31
+
32
+ /**
33
+ * The current translate of the transform.
34
+ */
35
+ translate: { x: number; y: number };
36
+
37
+ /**
38
+ * Set the translate of the transform
39
+ * @param point - the point to translate to
40
+ * @param options - motion options to apply to the transform (defaults to the motion options passed to the component)
41
+ */
42
+ setTranslate(point: { x: number; y: number }, options?: MotionProp): void;
43
+
44
+ /**
45
+ * Whether the transform is currently being moved
46
+ */
47
+ moving: boolean;
48
+
49
+ /**
50
+ * Whether the transform is currently being dragged
51
+ */
52
+ dragging: boolean;
53
+
54
+ /**
55
+ * The scroll mode of the transform.
56
+ *
57
+ * - `scale`: Scrolling will zoom in/out the canvas.
58
+ * - `translate`: Scrolling will pan the canvas.
59
+ * - `none`: No scroll mode is applied.
60
+ */
61
+ scrollMode: TransformScrollMode;
62
+
63
+ /**
64
+ * Set the scroll mode of the transform
65
+ *
66
+ * @param mode - the scroll mode to set
67
+ */
19
68
  setScrollMode(mode: TransformScrollMode): void;
69
+
70
+ /**
71
+ * Reset the transform to its initial state
72
+ */
20
73
  reset(): void;
74
+
75
+ /**
76
+ * Zoom in the transform
77
+ */
21
78
  zoomIn(): void;
79
+
80
+ /**
81
+ * Zoom out the transform
82
+ *
83
+ */
22
84
  zoomOut(): void;
85
+
86
+ /**
87
+ * Translate the transform to the center of the canvas
88
+ */
23
89
  translateCenter(): void;
90
+
91
+ /**
92
+ * Zoom to a specific point in the canvas
93
+ *
94
+ * @param center - The point (in chart coordinates) that should become the new
95
+ * center of the view after zooming.
96
+ *
97
+ * @param rect - A rectangular region (in chart coordinates) that the view should scale to fit.
98
+ * If omitted, the scale defaults to 1 (no zoom).
99
+ */
24
100
  zoomTo(center: { x: number; y: number }, rect?: { width: number; height: number }): void;
25
101
  };
26
102
 
27
- export type TransformContext = TransformContextValue;
28
-
29
- const defaultTranslate = writable({ x: 0, y: 0 });
30
- const defaultScale = writable(1);
31
- const defaultContext: TransformContext = {
32
- mode: 'none',
33
- scale: defaultScale,
34
- setScale: defaultScale.set,
35
- translate: defaultTranslate,
36
- setTranslate: defaultTranslate.set,
37
- moving: writable(false),
38
- dragging: writable(false),
39
- scrollMode: writable('none'),
40
- setScrollMode: () => {},
41
- reset: () => {},
42
- zoomIn: () => {},
43
- zoomOut: () => {},
44
- translateCenter: () => {},
45
- zoomTo: () => {},
46
- };
47
- export function transformContext() {
48
- return getContext<TransformContext>(transformContextKey) ?? defaultContext;
103
+ const _TransformContext = new Context<TransformContextValue>('TransformContext');
104
+
105
+ function createDefaultTransformContext() {
106
+ let defaultTranslate = $state(DEFAULT_TRANSLATE);
107
+ let defaultScale = $state(DEFAULT_SCALE);
108
+
109
+ const defaultContext: TransformContextValue = {
110
+ mode: 'none',
111
+ get scale() {
112
+ return defaultScale;
113
+ },
114
+ setScale: (value: number) => {
115
+ defaultScale = value;
116
+ },
117
+ get translate() {
118
+ return defaultTranslate;
119
+ },
120
+ setTranslate: (value: { x: 0; y: 0 }) => {
121
+ defaultTranslate = value;
122
+ },
123
+ moving: false,
124
+ dragging: false,
125
+ scrollMode: 'none',
126
+ setScrollMode: () => {},
127
+ reset: () => {},
128
+ zoomIn: () => {},
129
+ zoomOut: () => {},
130
+ translateCenter: () => {},
131
+ zoomTo: () => {},
132
+ };
133
+ return defaultContext;
49
134
  }
50
135
 
51
- function setTransformContext(transform: TransformContext) {
52
- setContext(transformContextKey, transform);
136
+ export function getTransformContext() {
137
+ return _TransformContext.getOr(createDefaultTransformContext());
53
138
  }
54
- </script>
55
-
56
- <script lang="ts">
57
- import { chartContext } from './ChartContext.svelte';
58
- import { motionStore, type MotionOptions, motionFinishHandler } from '../stores/motionStore.js';
59
- import { localPoint } from '@layerstack/utils';
60
139
 
61
- const { width, height, padding } = chartContext();
62
-
63
- export let mode: TransformMode = 'none';
64
-
65
- export let spring: boolean | Parameters<typeof motionStore>[1]['spring'] = undefined;
66
- export let tweened: boolean | Parameters<typeof motionStore>[1]['tweened'] = undefined;
140
+ export function setTransformContext(transform: TransformContextValue) {
141
+ return _TransformContext.set(transform);
142
+ }
67
143
 
68
- export let processTranslate = (x: number, y: number, deltaX: number, deltaY: number) => {
69
- return {
70
- x: x + deltaX,
71
- y: y + deltaY,
144
+ type TransformContextPropsWithoutHTML = {
145
+ mode?: TransformMode;
146
+ processTranslate?: (
147
+ x: number,
148
+ y: number,
149
+ deltaX: number,
150
+ deltaY: number
151
+ ) => {
152
+ x: number;
153
+ y: number;
72
154
  };
155
+ /**
156
+ * Disable pointer events including move/dragging. Useful for `mode="canvas" but only want
157
+ * zoomTo() interactions
158
+ *
159
+ * @default false
160
+ */
161
+ disablePointer?: boolean;
162
+
163
+ /**
164
+ * A bindable reference to the transform context value.
165
+ *
166
+ * @bindable
167
+ */
168
+ transformContext?: TransformContextValue;
169
+
170
+ /**
171
+ * Initial scroll mode.
172
+ * This is set to `none` by default, but can be set to `scale` or `translate`
173
+ *
174
+ * @default 'none'
175
+ */
176
+ initialScrollMode?: TransformScrollMode;
177
+
178
+ /**
179
+ * Distance/threshold to consider drag vs click (disable click propagation)
180
+ *
181
+ * @default 10
182
+ */
183
+ clickDistance?: number;
184
+
185
+ /**
186
+ * Initial translate value
187
+ */
188
+ initialTranslate?: { x: number; y: number };
189
+
190
+ /**
191
+ * Initial scale value
192
+ */
193
+ initialScale?: number;
194
+
195
+ /**
196
+ * A callback function that is called when the transform is applied.
197
+ * @param e
198
+ */
199
+ onTransform?: (details: { scale: number; translate: { x: number; y: number } }) => void;
200
+
201
+ ondragstart?: () => void;
202
+ ondragend?: () => void;
203
+ ref?: HTMLElement;
204
+ children?: Snippet<[{ transformContext: TransformContextValue }]>;
205
+
206
+ motion?: MotionProp;
73
207
  };
74
208
 
75
- /** Disable pointer events including move/dragging. Useful for `mode="canvas" but only want zoomTo() interactions */
76
- export let disablePointer = false;
209
+ type TransformContextProps = TransformContextPropsWithoutHTML &
210
+ Without<HTMLAttributes<HTMLElement>, TransformContextPropsWithoutHTML>;
211
+ </script>
77
212
 
78
- /** Action to take during wheel scroll */
79
- export let initialScrollMode: TransformScrollMode = 'none';
213
+ <script lang="ts">
214
+ import { localPoint } from '@layerstack/utils';
215
+ import { Context, watch } from 'runed';
216
+ import type { Without } from '../utils/types.js';
217
+ import { getChartContext } from './Chart.svelte';
218
+ import type { Snippet } from 'svelte';
219
+ import { cls } from '@layerstack/tailwind';
220
+ import { layerClass } from '../utils/attributes.js';
221
+ import {
222
+ createControlledMotion,
223
+ createMotionTracker,
224
+ parseMotionProp,
225
+ type MotionProp,
226
+ } from '../utils/motion.svelte.js';
227
+
228
+ let {
229
+ mode = 'none',
230
+ motion,
231
+ processTranslate = (x: number, y: number, deltaX: number, deltaY: number) => ({
232
+ x: x + deltaX,
233
+ y: y + deltaY,
234
+ }),
235
+ disablePointer = false,
236
+ initialScrollMode = 'none',
237
+ clickDistance = 10,
238
+ ondragend = () => {},
239
+ ondragstart = () => {},
240
+ onTransform = () => {},
241
+ initialTranslate,
242
+ initialScale,
243
+ onwheel = () => {},
244
+ onpointerdown = () => {},
245
+ onpointermove = () => {},
246
+ ontouchmove = () => {},
247
+ onpointerup = () => {},
248
+ ondblclick = () => {},
249
+ onclickcapture = () => {},
250
+ ref: refProp = $bindable(),
251
+ children,
252
+ class: className,
253
+ transformContext = $bindable(),
254
+ ...restProps
255
+ }: TransformContextProps = $props();
256
+
257
+ let ref = $state<HTMLElement>();
258
+ $effect.pre(() => {
259
+ refProp = ref;
260
+ });
80
261
 
81
- /** Distance/threshold to consider drag vs click (disable click propagation) */
82
- export let clickDistance = 10;
262
+ transformContext = {
263
+ get mode() {
264
+ return mode;
265
+ },
266
+ get scale() {
267
+ return scale.current;
268
+ },
269
+ setScale,
270
+ get translate() {
271
+ return translate.current;
272
+ },
273
+ setTranslate,
274
+ get dragging() {
275
+ return dragging;
276
+ },
277
+ get moving() {
278
+ return moving;
279
+ },
280
+ reset,
281
+ zoomIn,
282
+ zoomOut,
283
+ translateCenter,
284
+ zoomTo,
285
+ get scrollMode() {
286
+ return scrollMode;
287
+ },
288
+ setScrollMode,
289
+ };
83
290
 
84
- export let ondragstart: (() => void) | undefined = undefined;
85
- export let ondragend: (() => void) | undefined = undefined;
86
- export let ontransform:
87
- | ((e: { scale: number; translate: { x: number; y: number } }) => void)
88
- | undefined = undefined;
291
+ const ctx = getChartContext();
89
292
 
90
293
  let pointerDown = false;
91
- const dragging = writable(false);
92
- const scrollMode = writable<TransformScrollMode>(initialScrollMode);
294
+ let dragging = $state(false);
295
+ let scrollMode = $state<TransformScrollMode>(initialScrollMode);
93
296
 
94
- const DEFAULT_TRANSLATE = { x: 0, y: 0 };
95
- export let initialTranslate: { x: number; y: number } | undefined = undefined;
96
- export const translate = motionStore(initialTranslate ?? DEFAULT_TRANSLATE, { spring, tweened });
297
+ const resolvedMotion = parseMotionProp(motion);
97
298
 
98
- const DEFAULT_SCALE = 1;
99
- export let initialScale: number | undefined = undefined;
100
- export const scale = motionStore(initialScale ?? DEFAULT_SCALE, { spring, tweened });
299
+ const translate = createControlledMotion(initialTranslate ?? DEFAULT_TRANSLATE, resolvedMotion);
300
+ const scale = createControlledMotion(initialScale ?? DEFAULT_SCALE, resolvedMotion);
101
301
 
102
302
  let startPoint: { x: number; y: number } = { x: 0, y: 0 };
103
303
  let startTranslate: { x: number; y: number } = { x: 0, y: 0 };
104
304
 
105
305
  export function setScrollMode(mode: TransformScrollMode) {
106
- $scrollMode = mode;
306
+ scrollMode = mode;
107
307
  }
108
308
 
109
309
  export function reset() {
110
- $translate = initialTranslate ?? DEFAULT_TRANSLATE;
111
- $scale = initialScale ?? DEFAULT_SCALE;
310
+ translate.target = initialTranslate ?? DEFAULT_TRANSLATE;
311
+ scale.target = initialScale ?? DEFAULT_SCALE;
112
312
  }
113
313
 
114
314
  export function zoomIn() {
115
- scaleTo(1.25, { x: ($width + $padding.left) / 2, y: ($height + $padding.top) / 2 });
315
+ scaleTo(1.25, { x: (ctx.width + ctx.padding.left) / 2, y: (ctx.height + ctx.padding.top) / 2 });
116
316
  }
117
317
 
118
318
  export function zoomOut() {
119
- scaleTo(0.8, { x: ($width + $padding.left) / 2, y: ($height + $padding.top) / 2 });
319
+ scaleTo(0.8, { x: (ctx.width + ctx.padding.left) / 2, y: (ctx.height + ctx.padding.top) / 2 });
120
320
  }
121
321
 
122
322
  export function translateCenter() {
123
- $translate = {
323
+ translate.target = {
124
324
  x: 0,
125
325
  y: 0,
126
326
  };
@@ -130,32 +330,38 @@
130
330
  center: { x: number; y: number },
131
331
  rect?: { width: number; height: number }
132
332
  ) {
133
- const newScale = rect ? ($width < $height ? $width / rect.width : $height / rect.height) : 1;
134
-
135
- $translate = {
136
- x: $width / 2 - center.x * newScale,
137
- y: $height / 2 - center.y * newScale,
333
+ const newScale = rect
334
+ ? ctx.width < ctx.height
335
+ ? ctx.width / rect.width
336
+ : ctx.height / rect.height
337
+ : 1;
338
+
339
+ translate.target = {
340
+ x: ctx.width / 2 - center.x * newScale,
341
+ y: ctx.height / 2 - center.y * newScale,
138
342
  };
139
343
 
140
344
  if (rect) {
141
- $scale = newScale;
345
+ scale.target = newScale;
142
346
  }
143
347
  }
144
348
 
145
- function onPointerDown(e: PointerEvent & { currentTarget: HTMLDivElement }) {
349
+ function onPointerDown(e: PointerEvent & { currentTarget: HTMLElement }) {
350
+ onpointerdown?.(e);
146
351
  if (mode === 'none' || disablePointer) return;
147
352
 
148
353
  e.preventDefault();
149
354
 
150
355
  pointerDown = true;
151
- $dragging = false;
356
+ dragging = false;
152
357
  startPoint = localPoint(e);
153
- startTranslate = $translate;
358
+ startTranslate = translate.current;
154
359
 
155
360
  ondragstart?.();
156
361
  }
157
362
 
158
- function onPointerMove(e: PointerEvent & { currentTarget: HTMLDivElement }) {
363
+ function onPointerMove(e: PointerEvent & { currentTarget: HTMLElement }) {
364
+ onpointermove?.(e);
159
365
  if (!pointerDown) return;
160
366
 
161
367
  e.preventDefault(); // Stop text selection
@@ -164,44 +370,51 @@
164
370
  const deltaX = endPoint.x - startPoint.x;
165
371
  const deltaY = endPoint.y - startPoint.y;
166
372
 
167
- if (!$dragging) {
373
+ if (!dragging) {
168
374
  // If dragged beyond threshold, disable click propagation
169
- $dragging = deltaX * deltaX + deltaY * deltaY > clickDistance;
375
+ dragging = deltaX * deltaX + deltaY * deltaY > clickDistance;
170
376
  }
171
377
 
172
- if ($dragging) {
378
+ if (dragging) {
173
379
  e.stopPropagation(); // Stop tooltip from trigging (along with `capture: true`)
174
380
  e.currentTarget?.setPointerCapture(e.pointerId);
175
381
 
176
382
  setTranslate(
177
383
  processTranslate(startTranslate.x, startTranslate.y, deltaX, deltaY),
178
- // @ts-expect-error
179
- spring ? { hard: true } : tweened ? { duration: 0 } : undefined
384
+ translate.type === 'spring'
385
+ ? { instant: true }
386
+ : translate.type === 'tween'
387
+ ? { duration: 0 }
388
+ : undefined
180
389
  );
181
390
  }
182
391
  }
183
392
 
184
- function onPointerUp(e: PointerEvent) {
393
+ function onPointerUp(e: PointerEvent & { currentTarget: HTMLElement }) {
394
+ onpointerup?.(e);
185
395
  pointerDown = false;
186
- $dragging = false;
396
+ dragging = false;
187
397
  ondragend?.();
188
398
  }
189
399
 
190
- function onClick(e: MouseEvent) {
191
- if ($dragging) {
400
+ function onClick(e: MouseEvent & { currentTarget: HTMLElement }) {
401
+ onclickcapture?.(e);
402
+ if (dragging) {
192
403
  // Do not propagate click event to children if drag/moved. Registered in capture phase (top-down)
193
404
  e.stopPropagation();
194
405
  }
195
406
  }
196
407
 
197
- function onDoubleClick(e: MouseEvent) {
408
+ function onDoubleClick(e: MouseEvent & { currentTarget: HTMLElement }) {
409
+ ondblclick?.(e);
198
410
  if (mode === 'none' || disablePointer) return;
199
411
  const point = localPoint(e);
200
412
  scaleTo(e.shiftKey ? 0.5 : 2, point);
201
413
  }
202
414
 
203
- function onWheel(e: WheelEvent) {
204
- if (mode === 'none' || disablePointer || $scrollMode === 'none') return;
415
+ function onWheel(e: WheelEvent & { currentTarget: HTMLElement }) {
416
+ onwheel?.(e);
417
+ if (mode === 'none' || disablePointer || scrollMode === 'none') return;
205
418
 
206
419
  e.preventDefault();
207
420
 
@@ -210,7 +423,7 @@
210
423
  // Pinch to zoom is registered as a wheel event with control key
211
424
  const pinchToZoom = e.ctrlKey;
212
425
 
213
- if ($scrollMode === 'scale' || pinchToZoom) {
426
+ if (scrollMode === 'scale' || pinchToZoom) {
214
427
  // https://github.com/d3/d3-zoom#zoom_wheelDelta
215
428
  const scaleBy =
216
429
  -e.deltaY * (e.deltaMode === 1 ? 0.05 : e.deltaMode ? 1 : 0.002) * (e.ctrlKey ? 10 : 1);
@@ -218,16 +431,25 @@
218
431
  scaleTo(
219
432
  Math.pow(2, scaleBy),
220
433
  point,
221
- // @ts-expect-error
222
- spring ? { hard: true } : tweened ? { duration: 0 } : undefined
434
+ scale.type === 'spring'
435
+ ? { instant: true }
436
+ : scale.type === 'tween'
437
+ ? { duration: 0 }
438
+ : undefined
223
439
  );
224
- } else if ($scrollMode === 'translate') {
225
- translate.update(
226
- (startTranslate) =>
440
+ } else if (scrollMode === 'translate') {
441
+ const startTranslate = translate.current;
442
+ translate
443
+ .set(
227
444
  processTranslate(startTranslate.x, startTranslate.y, -e.deltaX, -e.deltaY),
228
- // @ts-expect-error
229
- spring ? { hard: true } : tweened ? { duration: 0 } : undefined
230
- );
445
+ translate.type === 'spring'
446
+ ? { instant: true }
447
+ : translate.type === 'tween'
448
+ ? { duration: 0 }
449
+ : undefined
450
+ )
451
+ .then(() => {})
452
+ .catch(() => {});
231
453
  }
232
454
  }
233
455
 
@@ -237,73 +459,56 @@
237
459
  function scaleTo(
238
460
  value: number,
239
461
  point: { x: number; y: number },
240
- options: Parameters<typeof motionStore>[1] | undefined = undefined
462
+ options: Parameters<(typeof scale)['set']>[1] | undefined = undefined
241
463
  ) {
242
- const currentScale = $scale;
243
- const newScale = $scale * value;
464
+ const currentScale = scale.current;
465
+ const newScale = scale.current * value;
244
466
  setScale(newScale, options);
245
467
 
246
468
  // Translate towards point (ex. mouse cursor/center) while zooming in/out
247
469
  const invertTransformPoint = {
248
- x: (point.x - $padding.left - $translate.x) / currentScale,
249
- y: (point.y - $padding.top - $translate.y) / currentScale,
470
+ x: (point.x - ctx.padding.left - translate.current.x) / currentScale,
471
+ y: (point.y - ctx.padding.top - translate.current.y) / currentScale,
250
472
  };
251
473
  const newTranslate = {
252
- x: point.x - $padding.left - invertTransformPoint.x * newScale,
253
- y: point.y - $padding.top - invertTransformPoint.y * newScale,
474
+ x: point.x - ctx.padding.left - invertTransformPoint.x * newScale,
475
+ y: point.y - ctx.padding.top - invertTransformPoint.y * newScale,
254
476
  };
255
477
  setTranslate(newTranslate, options);
256
478
  }
257
479
 
258
- const translating = motionFinishHandler();
259
- const scaling = motionFinishHandler();
260
- const moving = derived(
261
- [dragging, translating, scaling],
262
- ([dragging, translating, scaling]) => dragging || translating || scaling
263
- );
264
- export function setTranslate(point: { x: number; y: number }, options?: MotionOptions) {
265
- // @ts-expect-error
480
+ const translating = createMotionTracker();
481
+ const scaling = createMotionTracker();
482
+
483
+ const moving = $derived(dragging || translating.current || scaling.current);
484
+
485
+ export function setTranslate(
486
+ point: { x: number; y: number },
487
+ options?: Parameters<(typeof translate)['set']>[1]
488
+ ) {
266
489
  translating.handle(translate.set(point, options));
267
490
  }
268
491
 
269
- export function setScale(value: number, options?: MotionOptions) {
270
- // @ts-expect-error
492
+ export function setScale(value: number, options?: MotionProp) {
271
493
  scaling.handle(scale.set(value, options));
272
494
  }
273
495
 
274
- $: center = { x: $width / 2, y: $height / 2 };
275
-
276
- $: viewportCenter = {
277
- x: center.x - $translate.x,
278
- y: center.y - $translate.y,
279
- };
280
-
281
- $: ontransform?.({ scale: $scale, translate: $translate });
282
-
283
- setTransformContext({
284
- mode,
285
- scale,
286
- setScale,
287
- translate,
288
- setTranslate,
289
- dragging,
290
- moving,
291
- reset,
292
- zoomIn,
293
- zoomOut,
294
- translateCenter,
295
- zoomTo,
296
- scrollMode,
297
- setScrollMode,
496
+ watch([() => scale.current, () => translate.current], () => {
497
+ onTransform({
498
+ scale: scale.current,
499
+ translate: translate.current,
500
+ });
298
501
  });
502
+
503
+ setTransformContext(transformContext);
299
504
  </script>
300
505
 
301
- <!-- svelte-ignore a11y-no-static-element-interactions -->
302
506
  <div
303
- on:wheel={onWheel}
304
- on:pointerdown={onPointerDown}
305
- on:pointermove={onPointerMove}
306
- on:touchmove={(e) => {
507
+ onwheel={onWheel}
508
+ onpointerdown={onPointerDown}
509
+ onpointermove={onPointerMove}
510
+ ontouchmove={(e) => {
511
+ ontouchmove?.(e);
307
512
  // Touch events cause pointer events to be interrupted.
308
513
  // Typically `touch-action: none` works, but doesn't appear to with SVG, but `preventDefault()` works here
309
514
  // https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events#touch-action_css_property
@@ -311,23 +516,12 @@
311
516
  e.preventDefault();
312
517
  }
313
518
  }}
314
- on:pointerup={onPointerUp}
315
- on:dblclick={onDoubleClick}
316
- on:click|capture={onClick}
317
- on:click
318
- on:keydown
319
- on:keyup
320
- on:keypress
321
- class="h-full"
519
+ onpointerup={onPointerUp}
520
+ ondblclick={onDoubleClick}
521
+ onclickcapture={onClick}
522
+ class={cls(layerClass('transform-context'), 'h-full', className)}
523
+ bind:this={ref}
524
+ {...restProps}
322
525
  >
323
- <slot
324
- transform={{
325
- scale: $scale,
326
- setScale,
327
- translate: $translate,
328
- setTranslate,
329
- zoomTo,
330
- reset,
331
- }}
332
- />
526
+ {@render children?.({ transformContext: transformContext })}
333
527
  </div>