Skip to content

Commit 217f822

Browse files
committed
Backport different lazy-loading
1 parent 13deafc commit 217f822

File tree

2 files changed

+72
-68
lines changed

2 files changed

+72
-68
lines changed

src/components/SplitEditor.tsx

Lines changed: 63 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,56 @@
11
import type * as monaco from "monaco-editor";
2-
import { Component, createRef, type RefObject } from "react";
2+
import { Component, createRef, lazy, Suspense } from "react";
33
import { ErrorBoundary } from "react-error-boundary";
4+
import { BarLoader } from "react-spinners";
45
import SplitPane from "react-split-pane";
56

67
import { getSplitConfig, saveSplitConfig } from "../config.js";
78
import type { SupportedEngine, SupportedFormat } from "../rendering.js";
8-
import EditorPane from "./EditorPane.js";
9-
import GraphPane from "./GraphPane.js";
9+
import type EditorPane from "./EditorPane.js";
10+
11+
const EditorLazy = lazy(() => import("./EditorPane.js"));
12+
const GraphPaneLazy = lazy(() => import("./GraphPane.js"));
1013

1114
type ErrorList = monaco.editor.IMarkerData[];
1215

13-
interface Props {
16+
export type SplitEditorProps = {
1417
initialSource: string;
1518
format: SupportedFormat;
1619
engine: SupportedEngine;
1720
onSourceChange?(source: string): void;
18-
}
21+
};
1922

20-
type State = SourceState | ErroredState;
21-
interface SourceState {
23+
type SplitEditorState = SourceState | ErroredState;
24+
type SourceState = {
2225
dotSrc: string;
23-
errors: undefined;
24-
lastKnownGoodSrc: undefined;
25-
}
26-
interface ErroredState {
27-
dotSrc: undefined;
26+
errors?: undefined;
27+
lastKnownGoodSrc?: undefined;
28+
};
29+
type ErroredState = {
30+
dotSrc?: undefined;
2831
errors: ErrorList;
2932
lastKnownGoodSrc?: string;
30-
}
33+
};
3134

32-
const createSourceState = (dotSrc: string): SourceState => ({
33-
dotSrc,
34-
errors: undefined,
35-
lastKnownGoodSrc: undefined,
36-
});
37-
const createErroredState = (
38-
errors: ErrorList,
39-
lastKnownGoodSrc?: string,
40-
): ErroredState => ({ dotSrc: undefined, errors, lastKnownGoodSrc });
35+
const loadingStyle = {
36+
position: "absolute",
37+
display: "flex",
38+
inset: "0",
39+
justifyContent: "center",
40+
alignItems: "center",
41+
} as const;
4142

42-
export default class SplitEditor extends Component<Props, State> {
43-
#editorPaneRef: RefObject<EditorPane | null> = createRef<EditorPane>();
43+
export default class SplitEditor extends Component<
44+
SplitEditorProps,
45+
SplitEditorState
46+
> {
47+
#editorPaneRef = createRef<EditorPane>();
4448

45-
constructor(props: Props) {
49+
constructor(props: SplitEditorProps) {
4650
super(props);
4751
const p = this.props;
4852

49-
this.state = createSourceState(p.initialSource);
53+
this.state = { dotSrc: p.initialSource };
5054
if (p.onSourceChange) p.onSourceChange(this.state.dotSrc);
5155
}
5256

@@ -64,14 +68,14 @@ export default class SplitEditor extends Component<Props, State> {
6468
const p = this.props;
6569
if (p.onSourceChange) p.onSourceChange(dotSrc);
6670

67-
this.setState(createSourceState(dotSrc));
71+
this.setState({ dotSrc });
6872
};
6973

7074
dotSourceErrored = (errors: ErrorList): void => {
71-
this.setState(prevState => {
72-
const lastKnownGoodSrc = prevState.dotSrc || prevState.lastKnownGoodSrc;
73-
return createErroredState(errors, lastKnownGoodSrc);
74-
});
75+
this.setState(prev => ({
76+
errors,
77+
lastKnownGoodSrc: prev.dotSrc || prev.lastKnownGoodSrc,
78+
}));
7579
};
7680

7781
render() {
@@ -88,20 +92,36 @@ export default class SplitEditor extends Component<Props, State> {
8892
{...({} as any)}
8993
>
9094
<ErrorBoundary fallback="Could not load editor">
91-
<EditorPane
92-
ref={this.#editorPaneRef}
93-
defaultValue={s.dotSrc}
94-
onChangeValue={this.dotSourceChanged}
95-
onValueError={this.dotSourceErrored}
96-
/>
95+
<Suspense
96+
fallback={
97+
<div style={loadingStyle}>
98+
<BarLoader />
99+
</div>
100+
}
101+
>
102+
<EditorLazy
103+
ref={this.#editorPaneRef}
104+
defaultValue={s.dotSrc}
105+
onChangeValue={this.dotSourceChanged}
106+
onValueError={this.dotSourceErrored}
107+
/>
108+
</Suspense>
97109
</ErrorBoundary>
98110
<ErrorBoundary fallback="Could not load graph preview">
99-
<GraphPane
100-
hasErrors={!!(s.errors && s.errors.length > 0)}
101-
dotSrc={s.dotSrc || s.lastKnownGoodSrc || ""}
102-
engine={p.engine}
103-
format={p.format}
104-
/>
111+
<Suspense
112+
fallback={
113+
<div style={loadingStyle}>
114+
<BarLoader />
115+
</div>
116+
}
117+
>
118+
<GraphPaneLazy
119+
hasErrors={!!(s.errors && s.errors.length > 0)}
120+
dotSrc={s.dotSrc || s.lastKnownGoodSrc || ""}
121+
engine={p.engine}
122+
format={p.format}
123+
/>
124+
</Suspense>
105125
</ErrorBoundary>
106126
</SplitPane>
107127
);

src/index.tsx

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
import { Component, createRef, lazy, type RefObject, Suspense } from "react";
1+
import { Component, createRef, type RefObject } from "react";
22
import { createRoot } from "react-dom/client";
33

44
import "bootstrap";
55
import "bootstrap/dist/css/bootstrap.min.css";
66

77
import "./index.scss";
88

9-
import BarLoader from "react-spinners/BarLoader";
109
import Navigation from "./components/Navigation";
10+
import SplitEditor from "./components/SplitEditor";
1111
import { getLastState, mergeStates, saveLastEngine } from "./config";
1212
import { FileSaver } from "./FileSaver";
1313
import { exportAs, type SupportedEngine, saveSource } from "./rendering";
@@ -19,8 +19,6 @@ import {
1919
supportedEngines,
2020
} from "./viz";
2121

22-
const LazySplitEditor = lazy(() => import("./components/SplitEditor"));
23-
2422
const defaultEngine = supportedEngines[1];
2523

2624
interface State {
@@ -32,12 +30,6 @@ interface Props {
3230
}
3331

3432
const defaultSource = tutorial;
35-
const loadingStyle = {
36-
position: "fixed",
37-
top: "50%",
38-
left: "50%",
39-
transform: "translate(-50%, -50%)",
40-
} as const;
4133

4234
class App extends Component<Props, State> {
4335
#currentSource: string | undefined = undefined;
@@ -114,21 +106,13 @@ class App extends Component<Props, State> {
114106
loadSample={this.#loadSample}
115107
share={this.#share}
116108
/>
117-
<Suspense
118-
fallback={
119-
<div style={loadingStyle}>
120-
<BarLoader />
121-
</div>
122-
}
123-
>
124-
<LazySplitEditor
125-
ref={this.#editorRef}
126-
initialSource={initialSource}
127-
format="svg"
128-
engine={s.engine}
129-
onSourceChange={this.#sourceChanged}
130-
/>
131-
</Suspense>
109+
<SplitEditor
110+
ref={this.#editorRef}
111+
initialSource={initialSource}
112+
format="svg"
113+
engine={s.engine}
114+
onSourceChange={this.#sourceChanged}
115+
/>
132116
</div>
133117
);
134118
}

0 commit comments

Comments
 (0)