Using A Mathfield with React
Theory of Operations
A mathfield behaves as a regular DOM element:
- define mathfields using the
<math-field>
tag in JSX - get a reference to the corresponding DOM element with the
useRef()
hook - customize the mathfield on mount with
useEffect(..., [])
hook
Using A Mathfield with React
To use a mathfield with React, import the MathLive library and use a <math-field>
tag.
import "//unpkg.com/mathlive";
import { useState } from "react";
export default function App() {
const [value, setValue] = useState("");
return (
<div>
<math-field
onInput={evt => setValue(evt.target.value)}
>
{value}
</math-field>
<p>Value: {value}</p>
</div>
);
}
export default App;
Using A Mathfield with React and TypeScript
To use a mathfield with React and TypeScript, you need to add TypeScript definitions for mathfield elements.
declare global {
namespace JSX {
interface IntrinsicElements {
'math-field': React.DetailedHTMLProps<React.HTMLAttributes<MathfieldElement>, MathfieldElement>;
}
}
}
import "//unpkg.com/mathlive";
import { useState } from "react";
export default function App({children}) {
const [value, setValue] = useState<string>("");
return (
<div>
<math-field
onInput={
(evt: React.ChangeEvent<HTMLElement>) =>
setValue(evt.target.value)
}
>
{children}
</math-field>
<p>Value: {value}</p>
</div>
);
}
Using LaTeX strings with JSX
To specify the initial value of the mathfield provide a LaTeX
string as a child of the <math-field>
tag.
However, since both JSX and LaTeX use curly braces, you need to escape the LaTeX braces. The easiest way to do this is to use a backtick string. The content of the backtick string will be interpreted as a JavaScript string, which means that the backslashes will need to be escaped as well.
<math-field>{`
\\frac{1}{2}
`}</math-field>
Customization
To customize a mathfield, use a useRef
callback.
With the current
property of the ref, you can access and manipulate all the
properties and methods that are specific to the mathfield (value
, selection
, insert()
,
etc...). See MathfieldElement.
import "./App.css";
import "//unpkg.com/mathlive";
import { useState, useEffect, useRef } from "react";
export default function App({children}) {
const [value, setValue] = useState("");
return (
<div className="App">
<math-field
ref={(el) => {
if (el === null) {
// When el is null, the mathfield is being destroyed
// You may want to unsubscribe from events here
return;
}
// Customize the mathfield when it is created
mf.current.mathVirtualKeyboardPolicy = "manual";
mf.current.addEventListener("focusin", (evt) =>
window.mathVirtualKeyboard.show()
);
mf.current.addEventListener("focusout", (evt) =>
window.mathVirtualKeyboard.hide()
}}
onInput={evt => setValue(evt.target.value)}
>
{children}
</math-field>
<p>Value: {value}</p>
</div>
);
}