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 */
@@ -58,40 +60,55 @@ type OnCreateMeta = {
5860} ;
5961
6062/**
61- * Props for the SolidUplot component
62- *
63- * @template T - The type of the plugin bus data structure
63+ * Events that can be passed to the SolidUplot component
6464 */
65- type SolidUplotProps < T extends VoidStruct = VoidStruct > = SolidUplotOptions < T > & {
66- /** Ref callback to access the chart container element */
67- readonly ref ?: ( el : HTMLDivElement ) => void ;
65+ type SolidUplotEvents = {
6866 /** Callback fired when the uPlot instance is created */
6967 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 ;
68+ /** Callback fired when the cursor moves */
69+ readonly onCursorMove ?: ( params : OnCursorMoveParams ) => void ;
9370} ;
9471
72+ /**
73+ * Props for the SolidUplot component
74+ *
75+ * @template T - The type of the plugin bus data structure
76+ */
77+ type SolidUplotProps < T extends VoidStruct = VoidStruct > = SolidUplotOptions < T > &
78+ SolidUplotEvents & {
79+ /** Class name for the chart container */
80+ readonly class ?: string ;
81+
82+ /** CSS styles for the chart container (position is managed internally) */
83+ readonly style ?: Omit < JSX . CSSProperties , "position" > ;
84+
85+ /** Ref callback to access the chart container element */
86+ readonly ref ?: Ref < HTMLDivElement > ;
87+
88+ /**
89+ * Enable automatic resizing to fit container.
90+ *
91+ * When true:
92+ * - Chart uses width/height props for initial render
93+ * - Then automatically adapts to container size changes
94+ * - If no width/height provided, uses sensible defaults (600x300)
95+ *
96+ * @default false
97+ */
98+ readonly autoResize ?: boolean ;
99+
100+ /**
101+ * Whether to reset scales when chart data is updated
102+ * @default true
103+ */
104+ readonly resetScales ?: boolean ;
105+ /**
106+ * Where to place children components relative to the chart
107+ * @default "top"
108+ */
109+ readonly childrenPlacement ?: ChildrenPlacement ;
110+ } ;
111+
95112/**
96113 * A SolidJS wrapper component for uPlot charts with enhanced features
97114 *
@@ -146,8 +163,10 @@ export const SolidUplot = <T extends VoidStruct = VoidStruct>(
146163 const [ local , options ] = splitProps ( _props , [
147164 "children" ,
148165 "childrenPlacement" ,
166+ "class" ,
149167 "autoResize" ,
150168 "onCreate" ,
169+ "onCursorMove" ,
151170 "style" ,
152171 "ref" ,
153172 ] ) ;
@@ -164,9 +183,16 @@ export const SolidUplot = <T extends VoidStruct = VoidStruct>(
164183 const size = ( ) => ( { width : updateableOptions . width , height : updateableOptions . height } ) ;
165184
166185 const chartPlugins = createMemo ( ( ) => {
167- return system . plugins . map ( ( plugin ) =>
186+ const plugins = system . plugins . map ( ( plugin ) =>
168187 typeof plugin === "function" ? plugin ( { bus : system . pluginBus } ) : plugin ,
169188 ) ;
189+
190+ // Add internal cursor move plugin if callback is provided
191+ if ( local . onCursorMove ) {
192+ plugins . push ( createCursorMovePlugin ( local . onCursorMove ) ) ;
193+ }
194+
195+ return plugins ;
170196 } ) ;
171197
172198 createEffect ( ( ) => {
@@ -229,9 +255,13 @@ export const SolidUplot = <T extends VoidStruct = VoidStruct>(
229255 } ) ;
230256 } ) ;
231257
258+ const classes = ( ) => ( local . class ? `solid-uplot ${ local . class } ` : "solid-uplot" ) ;
259+
232260 return (
233261 < div
234262 id = "solid-uplot-root"
263+ ref = { mergeRefs ( local . ref , ( el ) => ( container = el ) ) }
264+ class = { classes ( ) }
235265 style = { {
236266 display : "flex" ,
237267 "flex-direction" : local . childrenPlacement === "top" ? "column" : "column-reverse" ,
@@ -244,10 +274,6 @@ export const SolidUplot = <T extends VoidStruct = VoidStruct>(
244274 } ) ,
245275 ...local . style ,
246276 } }
247- ref = { ( el ) => {
248- container = el ;
249- local . ref ?.( el ) ;
250- } }
251277 >
252278 { local . children }
253279 </ div >
0 commit comments