import React, { Component, createRef } from 'react'; // Import JQuery, required for the functioning of the equation editor import $ from 'jquery'; import './EquationEditor.scss'; // eslint-disable-next-line @typescript-eslint/no-explicit-any (window as any).jQuery = $; // eslint-disable-next-line @typescript-eslint/no-require-imports require('mathquill/build/mathquill'); // eslint-disable-next-line @typescript-eslint/no-explicit-any (window as any).MathQuill = (window as any).MathQuill.getInterface(1); type EquationEditorProps = { onChange(latex: string): void; value: string; spaceBehavesLikeTab?: boolean; autoCommands: string; autoOperatorNames: string; onEnter?(): void; }; /** * @typedef {EquationEditorProps} props * @prop {Function} onChange Triggered when content of the equation editor changes * @prop {string} value Content of the equation handler * @prop {boolean}[false] spaceBehavesLikeTab Whether spacebar should simulate tab behavior * @prop {string} autoCommands List of commands for which you only have to type the name of the * command with a \ in front of it. Examples: pi theta rho sum * @prop {string} autoOperatorNames List of operators for which you only have to type the name of the * operator with a \ in front of it. Examples: sin cos tan * @prop {Function} onEnter Triggered when enter is pressed in the equation editor * @extends {Component} */ class EquationEditor extends Component { element: React.RefObject; // eslint-disable-next-line @typescript-eslint/no-explicit-any mathField: any; ignoreEditEvents: number; // Element needs to be in the class format and thus requires a constructor. The steps that are run // in the constructor is to make sure that React can succesfully communicate with the equation // editor. constructor(props: EquationEditorProps) { super(props); this.element = createRef(); this.mathField = null; // MathJax apparently fire 2 edit events on startup. this.ignoreEditEvents = 2; } componentDidMount() { const { onChange, value, spaceBehavesLikeTab, autoCommands, autoOperatorNames, onEnter } = this.props; const config = { handlers: { edit: () => { if (this.ignoreEditEvents <= 0) onChange(this.mathField.latex()); else this.ignoreEditEvents -= 1; }, enter: onEnter, }, spaceBehavesLikeTab, autoCommands, autoOperatorNames, }; // eslint-disable-next-line @typescript-eslint/no-explicit-any this.mathField = (window as any).MathQuill.MathField(this.element.current, config); this.mathField.latex(value || ''); } componentDidUpdate(prevProps: Readonly): void { !prevProps.value && this.mathField.latex(this.props.value || ''); } render() { return ; } } export default EquationEditor;