UNPKG

@readable-js/react-codemirror

Version:
122 lines 5.37 kB
import React, { useCallback, useEffect, useRef } from 'react'; import { generateCallStack } from '@readable-js/core'; import { basicSetup, EditorState, EditorView } from '@codemirror/basic-setup'; import { javascript } from '@codemirror/lang-javascript'; import { Compartment } from "@codemirror/state"; import { readablePlugin } from './codemirror-plugin/readable-plugin'; import { linter } from "@codemirror/lint"; import { syntaxTree } from '@codemirror/language'; function stateToCode(state) { // that won't be performant on large files, but that is not the purpose of readable-js return Array.from(state.doc.iterLines(1, state.doc.lines + 1)).join('\n'); } function _ReadableEditor(p) { var _a; const editorParentRef = useRef(null); const readableCompartment = useRef(new Compartment()); const generated = useRef(); const editor = useRef(null); const $range = useRef(null); const $minValue = useRef(null); const $maxValue = useRef(null); const $currentValue = useRef(null); const error = useRef(null); useEffect(() => { editor.current = new EditorView({ state: EditorState.create({ extensions: [ basicSetup, javascript(), readableCompartment.current.of([readablePlugin(getUpdatedCallStack, 0)]), linter(lintError, { delay: 250 }) ], doc: p.initialCode }), parent: editorParentRef.current, dispatch: (...e) => { editor.current.update(e); }, }); return () => { editor.current.destroy(); }; }, []); function lintError(view) { var _a; const diagnostics = []; syntaxTree(view.state).iterate({ enter: (type) => { console.log("typeof error.current! === 'string'"); console.log(error.current); console.log(typeof error.current); if (error.current && typeof error.current.index === 'number' && type.from >= error.current.index && error.current.index < type.to) { diagnostics.push({ from: type.from, to: type.to, severity: "error", message: error.current.description, }); } }, }); console.log(view.state.doc.length); // like undeclared function at root error if (error.current) { const str = (_a = error.current.message) !== null && _a !== void 0 ? _a : error.current; diagnostics.push({ from: 0, to: view.state.doc.length, severity: "error", message: str, }); } return diagnostics; } function getUpdatedCallStack(view, skipEvaluation) { if (!skipEvaluation) { generated.current = generateCallStack(stateToCode(view.state)); } if (!generated.current.error) { updateSlider(generated.current.calls.length); error.current = null; } else { console.log(generated.current.error); error.current = generated.current.error; } return generated.current.calls; } function updateSlider(length) { $range.current.setAttribute('min', '0'); $range.current.setAttribute('max', (length - 1) + ''); $range.current.setAttribute('value', Math.min(parseInt($range.current.value), length - 1) + ''); $minValue.current.innerText = '1'; $maxValue.current.innerText = length + ''; $currentValue.current.innerText = (Math.min(parseInt($range.current.value), length - 1) + 1) + ''; } const onInput = useCallback((e) => { // The only way to tell the plugin to update, because external data has changed ? editor.current.dispatch({ effects: readableCompartment.current.reconfigure([ readablePlugin(getUpdatedCallStack, e.target.value, true) ]) }); }, []); return (React.createElement("div", null, React.createElement("div", { className: "slide-container" }, React.createElement("div", null, "Current step: ", React.createElement("span", { className: "current-value", ref: $currentValue })), React.createElement("span", { className: "min-value", ref: $minValue }), React.createElement("input", { type: "range", defaultValue: "0", className: "slider", id: "myRange", onInput: onInput, ref: $range }), React.createElement("span", { className: "max-value", ref: $maxValue })), React.createElement("div", { ref: editorParentRef, style: (_a = p.codeMirrorParentStyle) !== null && _a !== void 0 ? _a : { background: 'white', color: 'black' } }))); } const ReadableEditor = React.memo(_ReadableEditor, (props, nextProps) => { return true; // stop ReadableEditor from re-rendering }); export { ReadableEditor }; //# sourceMappingURL=ReadableEditor.js.map