11import "uplot/dist/uPlot.min.css" ;
22
3+ import { mergeRefs , Ref } from "@solid-primitives/refs" ;
34import {
45 createEffect ,
56 createMemo ,
@@ -14,6 +15,7 @@ import {
1415import uPlot from "uplot" ;
1516
1617import type { SolidUplotPluginBus , UplotPluginFactory , VoidStruct } from "./createPluginBus" ;
18+ import { createCursorMovePlugin , type OnCursorMoveParams } from "./eventPlugins" ;
1719import { getSeriesData , type SeriesDatum } from "./utils/getSeriesData" ;
1820
1921/** Placement options for children components relative to the chart */
@@ -57,40 +59,52 @@ type OnCreateMeta = {
5759 readonly seriesData : SeriesDatum [ ] ;
5860} ;
5961
62+ type SolidUplotEvents = {
63+ /** Callback fired when the uPlot instance is created */
64+ readonly onCreate ?: ( u : uPlot , meta : OnCreateMeta ) => void ;
65+ /** Callback fired when the cursor moves */
66+ readonly onCursorMove ?: ( params : OnCursorMoveParams ) => void ;
67+ } ;
68+
6069/**
6170 * Props for the SolidUplot component
6271 *
6372 * @template T - The type of the plugin bus data structure
6473 */
65- type SolidUplotProps < T extends VoidStruct = VoidStruct > = SolidUplotOptions < T > & {
66- /** Ref callback to access the chart container element */
67- readonly ref ?: ( el : HTMLDivElement ) => void ;
68- /** Callback fired when the uPlot instance is created */
69- readonly onCreate ?: ( u : uPlot , meta : OnCreateMeta ) => void ;
70- /**
71- * Whether to reset scales when chart data is updated
72- * @default true
73- */
74- readonly resetScales ?: boolean ;
75- /** CSS styles for the chart container (position is managed internally) */
76- readonly style ?: Omit < JSX . CSSProperties , "position" > ;
77- /**
78- * Where to place children components relative to the chart
79- * @default "top"
80- */
81- readonly childrenPlacement ?: ChildrenPlacement ;
82- /**
83- * Enable automatic resizing to fit container.
84- *
85- * When true:
86- * - Chart uses width/height props for initial render
87- * - Then automatically adapts to container size changes
88- * - If no width/height provided, uses sensible defaults (600x300)
89- *
90- * @default false
91- */
92- readonly autoResize ?: boolean ;
93- } ;
74+ type SolidUplotProps < T extends VoidStruct = VoidStruct > = SolidUplotOptions < T > &
75+ SolidUplotEvents & {
76+ /** Class name for the chart container */
77+ readonly class ?: string ;
78+
79+ /** CSS styles for the chart container (position is managed internally) */
80+ readonly style ?: Omit < JSX . CSSProperties , "position" > ;
81+
82+ /** Ref callback to access the chart container element */
83+ readonly ref ?: Ref < HTMLDivElement > ;
84+
85+ /**
86+ * Enable automatic resizing to fit container.
87+ *
88+ * When true:
89+ * - Chart uses width/height props for initial render
90+ * - Then automatically adapts to container size changes
91+ * - If no width/height provided, uses sensible defaults (600x300)
92+ *
93+ * @default false
94+ */
95+ readonly autoResize ?: boolean ;
96+
97+ /**
98+ * Whether to reset scales when chart data is updated
99+ * @default true
100+ */
101+ readonly resetScales ?: boolean ;
102+ /**
103+ * Where to place children components relative to the chart
104+ * @default "top"
105+ */
106+ readonly childrenPlacement ?: ChildrenPlacement ;
107+ } ;
94108
95109/**
96110 * A SolidJS wrapper component for uPlot charts with enhanced features
@@ -146,8 +160,10 @@ export const SolidUplot = <T extends VoidStruct = VoidStruct>(
146160 const [ local , options ] = splitProps ( _props , [
147161 "children" ,
148162 "childrenPlacement" ,
163+ "class" ,
149164 "autoResize" ,
150165 "onCreate" ,
166+ "onCursorMove" ,
151167 "style" ,
152168 "ref" ,
153169 ] ) ;
@@ -164,9 +180,16 @@ export const SolidUplot = <T extends VoidStruct = VoidStruct>(
164180 const size = ( ) => ( { width : updateableOptions . width , height : updateableOptions . height } ) ;
165181
166182 const chartPlugins = createMemo ( ( ) => {
167- return system . plugins . map ( ( plugin ) =>
183+ const plugins = system . plugins . map ( ( plugin ) =>
168184 typeof plugin === "function" ? plugin ( { bus : system . pluginBus } ) : plugin ,
169185 ) ;
186+
187+ // Add internal cursor move plugin if callback is provided
188+ if ( local . onCursorMove ) {
189+ plugins . push ( createCursorMovePlugin ( local . onCursorMove ) ) ;
190+ }
191+
192+ return plugins ;
170193 } ) ;
171194
172195 createEffect ( ( ) => {
@@ -229,9 +252,13 @@ export const SolidUplot = <T extends VoidStruct = VoidStruct>(
229252 } ) ;
230253 } ) ;
231254
255+ const classes = ( ) => ( local . class ? `solid-uplot ${ local . class } ` : "solid-uplot" ) ;
256+
232257 return (
233258 < div
234259 id = "solid-uplot-root"
260+ ref = { mergeRefs ( local . ref , ( el ) => ( container = el ) ) }
261+ class = { classes ( ) }
235262 style = { {
236263 display : "flex" ,
237264 "flex-direction" : local . childrenPlacement === "top" ? "column" : "column-reverse" ,
@@ -244,10 +271,6 @@ export const SolidUplot = <T extends VoidStruct = VoidStruct>(
244271 } ) ,
245272 ...local . style ,
246273 } }
247- ref = { ( el ) => {
248- container = el ;
249- local . ref ?.( el ) ;
250- } }
251274 >
252275 { local . children }
253276 </ div >
0 commit comments