Skip to content

Commit eacad23

Browse files
committed
Fixed linter and formatting issued
1 parent 43e1f51 commit eacad23

File tree

2 files changed

+177
-176
lines changed

2 files changed

+177
-176
lines changed

src/components/CanvasEditor.tsx

Lines changed: 132 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -1,143 +1,149 @@
1-
import OCL, {Molecule, Reaction, ReactionEncoder} from 'openchemlib/full';
2-
import type {ReactElement} from 'react';
3-
import {useEffect, useRef} from 'react';
1+
import OCL, { Molecule, Reaction, ReactionEncoder } from 'openchemlib/full';
2+
import type { ReactElement } from 'react';
3+
import { useEffect, useRef } from 'react';
44

5-
export interface CanvasEditorProps
6-
{
7-
width?: number;
8-
height?: number;
9-
initialMolfile?: string;
10-
initialIDCode?: string;
11-
fragment?: boolean;
12-
mode?: OCL.CanvasEditorMode;
13-
onChange?: (molFile: string|null, molecule: OCL.Molecule | null, idCode: string | null) => void;
5+
export interface CanvasEditorProps {
6+
width?: number;
7+
height?: number;
8+
initialMolfile?: string;
9+
initialIDCode?: string;
10+
fragment?: boolean;
11+
mode?: OCL.CanvasEditorMode;
12+
onChange?: (
13+
molFile: string | null,
14+
molecule: OCL.Molecule | null,
15+
idCode: string | null,
16+
) => void;
1417
}
1518

16-
interface CallbacksRef
17-
{
18-
onChange?: OCL.OnChangeListenerCallback;
19+
interface CallbacksRef {
20+
onChange?: OCL.OnChangeListenerCallback;
1921
}
2022

21-
export default function CanvasEditor(
22-
props: CanvasEditorProps,
23-
): ReactElement {
24-
const {
25-
width = 675,
26-
height = 450,
27-
initialMolfile = '',
28-
initialIDCode = '',
29-
fragment = false,
30-
mode = "molecule",
31-
onChange,
32-
} = props;
33-
const reactionMode: boolean = mode === 'reaction';
23+
const decodeReaction = (idCode: string): Reaction => {
24+
let ret = Reaction.create();
25+
if (idCode?.trim().length > 0) {
26+
const frags: string[] = idCode.split(' ');
27+
if (frags.length > 0) {
28+
const rxn = ReactionEncoder.decode(idCode);
29+
if (rxn != null) {
30+
ret = rxn;
31+
}
32+
}
33+
}
34+
return ret;
35+
};
3436

35-
const domRef = useRef<HTMLDivElement>(null);
36-
const editorRef = useRef<{
37-
editor: OCL.CanvasEditor | null;
38-
hadFirstChange: boolean;
39-
}>({editor: null, hadFirstChange: false});
40-
const callbacksRef = useRef<CallbacksRef>({});
37+
export default function CanvasEditor(props: CanvasEditorProps): ReactElement {
38+
const {
39+
width = 675,
40+
height = 450,
41+
initialMolfile = '',
42+
initialIDCode = '',
43+
fragment = false,
44+
mode = 'molecule',
45+
onChange,
46+
} = props;
47+
//const reactionMode: boolean = mode === 'reaction';
4148

42-
const decodeReaction = (idCode: string): Reaction => {
43-
let ret = Reaction.create();
44-
if (idCode?.trim().length > 0) {
45-
const frags: string[] = idCode.split(" ");
46-
if (frags.length > 0) {
47-
const rxn = ReactionEncoder.decode(idCode);
48-
if (rxn != null)
49-
ret = rxn;
50-
}
51-
}
52-
return ret;
53-
};
49+
const domRef = useRef<HTMLDivElement>(null);
50+
const editorRef = useRef<{
51+
editor: OCL.CanvasEditor | null;
52+
hadFirstChange: boolean;
53+
}>({ editor: null, hadFirstChange: false });
54+
const callbacksRef = useRef<CallbacksRef>({});
5455

55-
useEffect(() => {
56-
if (!domRef.current)
57-
return;
56+
useEffect(() => {
57+
if (!domRef.current) {
58+
return;
59+
}
5860

59-
domRef.current.innerHTML = '';
61+
domRef.current.innerHTML = '';
6062

61-
// GWT doesn't play well with the shadow DOM. This hack allows to load an
62-
// OCL editor inside a shadow root.
63-
const root = domRef.current.getRootNode();
64-
let originalGetElementById: typeof document.getElementById | undefined;
65-
if (root instanceof ShadowRoot) {
66-
// eslint-disable-next-line @typescript-eslint/unbound-method
67-
originalGetElementById = document.getElementById;
68-
document.getElementById = root.getElementById.bind(root);
69-
}
70-
let editor;
71-
try {
72-
editor = new OCL.CanvasEditor(domRef.current, {initialMode: mode});
73-
} finally {
74-
if (originalGetElementById) {
75-
document.getElementById = originalGetElementById;
76-
}
77-
}
63+
// GWT doesn't play well with the shadow DOM. This hack allows to load an
64+
// OCL editor inside a shadow root.
65+
const root = domRef.current.getRootNode();
66+
let originalGetElementById: typeof document.getElementById | undefined;
67+
if (root instanceof ShadowRoot) {
68+
// eslint-disable-next-line @typescript-eslint/unbound-method
69+
originalGetElementById = document.getElementById;
70+
document.getElementById = root.getElementById.bind(root);
71+
}
72+
let editor;
73+
try {
74+
editor = new OCL.CanvasEditor(domRef.current, { initialMode: mode });
75+
} finally {
76+
if (originalGetElementById) {
77+
document.getElementById = originalGetElementById;
78+
}
79+
}
7880

79-
editorRef.current.editor = editor;
81+
editorRef.current.editor = editor;
8082

81-
if (initialMolfile && initialIDCode) {
82-
throw new Error('Cannot specify both initialMolfile and initialIDCode');
83-
}
84-
if (initialMolfile) {
85-
if (reactionMode)
86-
editor.setReaction(Reaction.fromRxn(initialMolfile));
87-
else
88-
editor.setMolecule(Molecule.fromMolfile(initialMolfile));
89-
}
90-
if (initialIDCode) {
91-
if (reactionMode)
92-
editor.setReaction(decodeReaction(initialMolfile));
93-
else
94-
editor.setMolecule(Molecule.fromIDCode(initialIDCode));
95-
}
96-
editor.getMolecule().setFragment(fragment);
97-
editor.setOnChangeListener((event) => {
98-
if (callbacksRef.current.onChange) {
99-
callbacksRef.current.onChange(event);
100-
}
101-
});
102-
// eslint-disable-next-line react-hooks/exhaustive-deps
103-
}, [width, height]);
104-
105-
106-
useEffect(() => {
107-
callbacksRef.current.onChange = () => {
108-
if (!editorRef.current.hadFirstChange) {
109-
editorRef.current.hadFirstChange = true;
110-
} else {
111-
const editor = editorRef.current.editor;
112-
if (onChange && editor) {
113-
if (!reactionMode) {
114-
const molfile = editor.getMolecule().toMolfile()
115-
const molecule = editor.getMolecule();
116-
const idCode = editor.getMolecule().getIDCode();
117-
onChange(molfile, molecule, idCode);
118-
} else {
119-
const reaction = editor.getReaction();
120-
const idCode = ReactionEncoder.encode(reaction, {});
121-
onChange(null,null,idCode);
122-
}
123-
}
124-
}
125-
};
126-
}, [onChange]);
83+
if (initialMolfile && initialIDCode) {
84+
throw new Error('Cannot specify both initialMolfile and initialIDCode');
85+
}
86+
if (initialMolfile) {
87+
if (mode === 'reaction') {
88+
editor.setReaction(Reaction.fromRxn(initialMolfile));
89+
} else {
90+
editor.setMolecule(Molecule.fromMolfile(initialMolfile));
91+
}
92+
}
93+
if (initialIDCode) {
94+
if (mode === 'reaction') {
95+
editor.setReaction(decodeReaction(initialMolfile));
96+
} else {
97+
editor.setMolecule(Molecule.fromIDCode(initialIDCode));
98+
}
99+
}
100+
editor.getMolecule().setFragment(fragment);
101+
editor.setOnChangeListener((event) => {
102+
if (callbacksRef.current.onChange) {
103+
callbacksRef.current.onChange(event);
104+
}
105+
});
106+
// eslint-disable-next-line react-hooks/exhaustive-deps
107+
}, [width, height]);
127108

128-
useEffect(() => {
129-
if (editorRef.current.editor) {
130-
if (reactionMode) {
131-
editorRef.current.editor.setReaction(decodeReaction(initialIDCode));
132-
} else {
133-
editorRef.current.editor.setMolecule(Molecule.fromIDCode(initialIDCode));
134-
}
109+
useEffect(() => {
110+
callbacksRef.current.onChange = () => {
111+
if (!editorRef.current.hadFirstChange) {
112+
editorRef.current.hadFirstChange = true;
113+
} else {
114+
const editor = editorRef.current.editor;
115+
if (onChange && editor) {
116+
if (mode === 'molecule') {
117+
const molfile = editor.getMolecule().toMolfile();
118+
const molecule = editor.getMolecule();
119+
const idCode = editor.getMolecule().getIDCode();
120+
onChange(molfile, molecule, idCode);
121+
} else {
122+
const reaction = editor.getReaction();
123+
const idCode = ReactionEncoder.encode(reaction, {});
124+
onChange(null, null, idCode);
125+
}
135126
}
136-
}, [initialIDCode]);
127+
}
128+
};
129+
}, [onChange, mode]);
130+
131+
useEffect(() => {
132+
if (editorRef.current.editor) {
133+
if (mode === 'reaction') {
134+
editorRef.current.editor.setReaction(decodeReaction(initialIDCode));
135+
} else {
136+
editorRef.current.editor.setMolecule(
137+
Molecule.fromIDCode(initialIDCode),
138+
);
139+
}
140+
}
141+
}, [initialIDCode, mode]);
137142

138-
return <>
139-
<div>Structure Editor</div>
140-
<div ref={domRef} style={{width, height}}/>
141-
;
143+
return (
144+
<>
145+
<div>Structure Editor</div>
146+
<div ref={domRef} style={{ width, height }} />;
142147
</>
148+
);
143149
}

stories/canvas-editor.stories.tsx

Lines changed: 45 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,57 @@
1-
import { useCallback, useState } from 'react';
1+
import {useCallback, useState} from 'react';
22

33
import CanvasEditor from '../src/components/CanvasEditor.js';
44
import type {Molecule} from "openchemlib/full";
55

66
export default {
7-
title: 'CanvasEditor',
8-
component: CanvasEditor,
9-
args: {
10-
mode: "molecule",
11-
fragment: false,
12-
width: 675,
13-
height: 450,
14-
},
15-
parameters: {
16-
docs: {
17-
description: {
18-
component: 'StructureEditor is an uncontrolled component.',
19-
},
7+
title: 'CanvasEditor',
8+
component: CanvasEditor,
9+
args: {
10+
mode: "molecule",
11+
fragment: false,
12+
width: 675,
13+
height: 450,
14+
},
15+
parameters: {
16+
docs: {
17+
description: {
18+
component: 'StructureEditor is an uncontrolled component.',
19+
},
20+
},
2021
},
21-
},
2222
};
2323

2424
const initialIDCode = 'gJX@@eKU@@ gFp@DiTt@@@!gGQHDHaImfh@##!B_vp@[G|S@AL !BmpJH@ox@?`BH?@ !Bb@K~@Hc}b@JH?P';
2525

26-
export function TheCanvasEditor({
27-
mode,
28-
fragment,
29-
width,
30-
height,
31-
}: {
32-
mode: string;
33-
fragment: boolean;
34-
width: number;
35-
height: number;
36-
}) {
37-
const [idCode, setIDCode] = useState(initialIDCode);
38-
const [previous, setPrevious] = useState<string | null>(null);
39-
const cb = useCallback(
40-
(molfile: string | null, molecule: Molecule|null, newIDCode: | null) => {
41-
setIDCode(newIDCode);
42-
setPrevious(idCode);
43-
},
44-
[setIDCode, setPrevious, idCode],
45-
);
46-
return (
47-
<div>
48-
<h2>Editor</h2>
49-
<CanvasEditor initialIDCode={idCode} onChange={cb} mode={"reaction"}/>
50-
<div style={{ display: 'flex' }}>
51-
<div style={{ flex: 1 }}>
52-
<h2 style={{ textAlign: 'center' }}>Current</h2>
53-
<pre>{idCode}</pre>
54-
</div>
55-
<div style={{ flex: 1 }}>
56-
<h2 style={{ textAlign: 'center' }}>Previous</h2>
57-
<pre>{previous}</pre>
26+
export function TheCanvasEditor()
27+
{
28+
const [idCode, setIDCode] = useState(initialIDCode);
29+
const [previous, setPrevious] = useState<string | null>(null);
30+
const cb = useCallback(
31+
(molfile: string | null, molecule: Molecule | null, newIDCode: string | null) => {
32+
if (!newIDCode) {
33+
setIDCode("");
34+
} else {
35+
setIDCode(newIDCode);
36+
}
37+
setPrevious(idCode);
38+
},
39+
[setIDCode, setPrevious, idCode],
40+
);
41+
return (
42+
<div>
43+
<h2>Editor</h2>
44+
<CanvasEditor initialIDCode={idCode} onChange={cb} mode={"reaction"}/>
45+
<div style={{display: 'flex'}}>
46+
<div style={{flex: 1}}>
47+
<h2 style={{textAlign: 'center'}}>Current</h2>
48+
<pre>{idCode}</pre>
49+
</div>
50+
<div style={{flex: 1}}>
51+
<h2 style={{textAlign: 'center'}}>Previous</h2>
52+
<pre>{previous}</pre>
53+
</div>
54+
</div>
5855
</div>
59-
</div>
60-
</div>
61-
);
56+
);
6257
}

0 commit comments

Comments
 (0)