organic_ast_explorer/src/Editor.tsx
2024-01-27 14:27:22 -05:00

66 lines
1.8 KiB
TypeScript

import React, { ReactNode, useState } from "react";
import "./Editor.css";
import { Highlight } from "./highlight";
import { buildShadow } from "./shadow";
import OrgAst from "./OrgAst";
const default_org_source: string = `Welcome to the Organic Wasm Demo!
Type your Org [fn:1] source in this text box, and it will be parsed by Organic [fn:2] that has been compiled into wasm and embedded in this page. The resulting AST will be rendered to the right.
In the AST on the right, you can:
1. Click on an AST node to highlight the corresponding portion of the Org source on the left.
2. Expand/Collapse the children, properties, and standard properties.
* Footnotes
[fn:1] https://orgmode.org/
[fn:2] https://code.fizz.buzz/talexander/organic
`;
function Editor({ defaultValue = default_org_source }) {
function handleChange(event: React.ChangeEvent<HTMLTextAreaElement>) {
setValue(event.target.value);
}
const [value, setValue] = useState(defaultValue);
const [highlights, setHighlights] = useState<Array<Highlight>>([]);
function addHighlight(start: number, end: number) {
let new_highlights = [...highlights, new Highlight(start, end)];
new_highlights.sort(function (a, b) {
if (a.start < b.start) return -1;
if (a.start > b.start) return 1;
return 0;
});
setHighlights(new_highlights);
}
function clearHighlights() {
setHighlights([]);
}
if (highlights.length === 0) {
addHighlight(1, 5);
}
return (
<div className="Editor">
<div className="Editor-textwrapper">
<textarea
onChange={handleChange}
className="Editor-textarea"
value={value}
/>
<div className="Editor-underlay">{buildShadow(highlights, value)}</div>
</div>
<OrgAst addHighlight={addHighlight} value={value} />
</div>
);
}
export default Editor;