Skip to content

Commit dfbede0

Browse files
committed
WIP: Rearrange React stuff
1 parent 7cfbcff commit dfbede0

4 files changed

Lines changed: 56 additions & 38 deletions

File tree

src/GraphViewer.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
import { Graph } from "./Graph.js";
2-
import type { BlockPtr, Func, Pass, SampleCounts } from "./iongraph.js";
31
import { dequal } from "./dequal.js";
42
import { E } from "./dom.js";
3+
import { Graph } from "./Graph.js";
4+
import type { BlockPtr, Func, Pass, SampleCounts } from "./iongraph.js";
5+
6+
type KeyPasses = [number | null, number | null, number | null, number | null];
57

68
export interface GraphViewerProps {
79
func: Func,
@@ -10,8 +12,6 @@ export interface GraphViewerProps {
1012
sampleCounts?: SampleCounts,
1113
}
1214

13-
type KeyPasses = [number | null, number | null, number | null, number | null];
14-
1515
export class GraphViewer {
1616
func: Func;
1717
passNumber: number;
@@ -26,13 +26,13 @@ export class GraphViewer {
2626

2727
constructor(root: HTMLElement, {
2828
func,
29-
pass: propsPass = 0,
29+
pass = 0,
3030

3131
sampleCounts
3232
}: GraphViewerProps) {
3333
this.graph = null;
3434
this.func = func;
35-
this.passNumber = propsPass;
35+
this.passNumber = pass;
3636
this.sampleCounts = sampleCounts;
3737

3838
this.keyPasses = [null, null, null, null];
@@ -79,7 +79,7 @@ export class GraphViewer {
7979
div.style.position = "relative";
8080
})
8181
this.sidebarLinks = func.passes.map((pass, i) => (
82-
E("a", ["ig-link-normal", "ig-pv1", "ig-ph2", "ig-flex", "ig-g2",], a => {
82+
E("a", ["ig-link-normal", "ig-pv1", "ig-ph2", "ig-flex", "ig-g2"], a => {
8383
a.href = "#";
8484
a.addEventListener("click", e => {
8585
e.preventDefault();
@@ -100,12 +100,12 @@ export class GraphViewer {
100100
]);
101101
root.appendChild(this.container);
102102

103-
this.update();
104-
105103
this.keydownHandler = this.keydownHandler.bind(this);
106104
this.tweakHandler = this.tweakHandler.bind(this);
107105
window.addEventListener("keydown", this.keydownHandler);
108106
window.addEventListener("tweak", this.tweakHandler);
107+
108+
this.update();
109109
}
110110

111111
destroy() {

src/index-react.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
export * from "./index.js";
2-
export * from "./GraphViewer.js";
2+
export * from "./react-components.js";

src/react-components.tsx

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { useRef, useEffect } from "react";
2+
3+
import { GraphViewer } from "./GraphViewer.js";
4+
import { Func, SampleCounts } from "./iongraph.js";
5+
6+
export interface GraphViewerReactProps {
7+
func: Func,
8+
pass?: number,
9+
sampleCounts?: SampleCounts,
10+
11+
className?: string;
12+
style?: React.CSSProperties;
13+
}
14+
15+
export function GraphViewerReact(props: GraphViewerReactProps) {
16+
const root = useRef<HTMLDivElement>(null);
17+
const graphViewer = useRef<GraphViewer | null>(null);
18+
19+
useEffect(() => {
20+
if (graphViewer.current) {
21+
graphViewer.current.destroy();
22+
graphViewer.current = null;
23+
}
24+
if (root.current) {
25+
graphViewer.current = new GraphViewer(root.current, {
26+
func: props.func,
27+
pass: props.pass,
28+
29+
sampleCounts: props.sampleCounts,
30+
});
31+
}
32+
33+
return () => {
34+
graphViewer.current?.destroy();
35+
};
36+
}, [props.func, props.pass, props.sampleCounts]);
37+
38+
return <div ref={root} className={props.className} style={props.style} />
39+
};

www/main.tsx

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { ChangeEvent, useEffect, useRef, useState } from 'react';
2-
import { createRoot } from 'react-dom/client';
1+
import { ChangeEvent, useEffect, useState } from "react";
2+
import { createRoot } from "react-dom/client";
33

4-
import { GraphViewer, GraphViewerProps } from '../src/GraphViewer.js';
5-
import { migrate, type IonJSON, type Func, type MIRBlock, type SampleCounts } from '../src/iongraph.js';
6-
import { assert, must } from '../src/utils.js';
4+
import { migrate, type IonJSON, type Func, type SampleCounts } from "../src/iongraph.js";
5+
import { GraphViewerReact } from "../src/react-components.js";
6+
import { must } from "../src/utils.js";
77

88
export function renderWebUI(root: HTMLElement) {
99
const reactRoot = createRoot(root);
@@ -150,7 +150,7 @@ function WebUI() {
150150
<MenuBar browse export ionjson={initialIonJSON} funcSelected={f => setFunc(f)} />
151151
{
152152
func && <div className="ig-relative ig-flex-basis-0 ig-flex-grow-1 ig-overflow-hidden">
153-
<GraphViewer2
153+
<GraphViewerReact
154154
func={func}
155155
pass={initialPass}
156156
sampleCounts={sampleCounts}
@@ -160,27 +160,6 @@ function WebUI() {
160160
</div >;
161161
}
162162

163-
function GraphViewer2(props: GraphViewerProps) {
164-
const root = useRef<HTMLDivElement>(null);
165-
const graphViewer = useRef<GraphViewer | null>(null);
166-
167-
useEffect(() => {
168-
if (graphViewer.current) {
169-
graphViewer.current.destroy();
170-
graphViewer.current = null;
171-
}
172-
if (root.current) {
173-
graphViewer.current = new GraphViewer(root.current, props);
174-
}
175-
176-
return () => {
177-
graphViewer.current?.destroy();
178-
};
179-
});
180-
181-
return <div ref={root} />
182-
}
183-
184163
interface StandaloneUIProps {
185164
ionjson: IonJSON,
186165
}
@@ -191,7 +170,7 @@ function StandaloneUI(props: StandaloneUIProps) {
191170
<MenuBar ionjson={props.ionjson} funcSelected={f => setFunc(f)} />
192171
{
193172
func && <div className="ig-relative ig-flex-basis-0 ig-flex-grow-1 ig-overflow-hidden">
194-
<GraphViewer2
173+
<GraphViewerReact
195174
func={func}
196175
pass={initialPass}
197176
/>

0 commit comments

Comments
 (0)