@@ -15,6 +15,7 @@ import * as rerun from "@rerun-io/web-viewer";
1515 * @typedef {(
1616 * Omit<import("@rerun-io/web-viewer").WebViewerOptions, "allow_fullscreen" | "enable_history">
1717 * & BaseProps
18+ * & import("./types.d.ts").ViewerEvents
1819 * )} Props
1920 */
2021
@@ -43,7 +44,7 @@ export default class WebViewer extends React.Component {
4344 startViewer (
4445 this . #handle,
4546 /** @type {HTMLDivElement } */ ( this . #parent. current ) ,
46- this . props ,
47+ ( ) => this . props ,
4748 ) ;
4849 }
4950
@@ -65,7 +66,7 @@ export default class WebViewer extends React.Component {
6566 startViewer (
6667 this . #handle,
6768 /** @type {HTMLDivElement } */ ( this . #parent. current ) ,
68- this . props ,
69+ ( ) => this . props ,
6970 ) ;
7071 } else {
7172 // We only need to diff the recordings.
@@ -92,12 +93,33 @@ export default class WebViewer extends React.Component {
9293 }
9394}
9495
96+ /** @param {string } str */
97+ function pascalToSnake ( str ) {
98+ let out = "" ;
99+ for ( let i = 0 ; i < str . length ; i ++ ) {
100+ const code = str . charCodeAt ( i ) ;
101+
102+ // A–Z ?
103+ if ( code >= 65 && code <= 90 ) {
104+ // if not first char, prepend underscore
105+ if ( i > 0 ) out += "_" ;
106+ // convert to lowercase by adding 32
107+ out += String . fromCharCode ( code + 32 ) ;
108+ } else {
109+ // everything else (a–z, 0–9, etc.) goes straight through
110+ out += String . fromCharCode ( code ) ;
111+ }
112+ }
113+ return out ;
114+ }
115+
95116/**
96117 * @param {rerun.WebViewer } handle
97118 * @param {HTMLElement } parent
98- * @param {Props } props
119+ * @param {() => Props } getProps
99120 */
100- function startViewer ( handle , parent , props ) {
121+ function startViewer ( handle , parent , getProps ) {
122+ const props = getProps ( ) ;
101123 handle . start ( toArray ( props . rrd ) , parent , {
102124 manifest_url : props . manifest_url ,
103125 render_backend : props . render_backend ,
@@ -108,6 +130,16 @@ function startViewer(handle, parent, props) {
108130 width : "100%" ,
109131 height : "100%" ,
110132 } ) ;
133+
134+ for ( const key of Object . keys ( props ) ) {
135+ if ( key . startsWith ( "on" ) ) {
136+ /** @type {any } */
137+ const event = pascalToSnake ( key . slice ( 2 ) ) ;
138+ /** @type {any } */
139+ const callback = /** @type {any } */ ( getProps ( ) ) [ key ] ;
140+ handle . on ( event , callback ) ;
141+ }
142+ }
111143}
112144
113145/**
0 commit comments