Step 25: Rich Text Editor
We are going to use Mantine UI's Rich Text Editor. Let's add it as a dependency to our application:
yarn add @mantine/rte
Now we are going to update the Edit.jsx
:
-
Add
RichTextEditor
from@mantine/rte
instead ofTextarea
from@mantine/core
. -
Take our the
<Textarea />
component and instead add the following:<RichTextEditor id="rte" defaultValue={"Your note's text"} value={text} onChange={setText} />
-
Finally, delete
handleTextChange
function as you don't need it anymore!
Here is the updated Edit.jsx
import { Button, Container, Group, Stack } from "@mantine/core";
import { TextInput } from "@mantine/core";
import { useEffect, useState } from "react";
import PropTypes from "prop-types";
import { useNavigate, useLocation } from "react-router-dom";
import { RichTextEditor } from "@mantine/rte";
function Edit(props) {
const { edit, remove } = props;
const navigate = useNavigate();
const location = useLocation();
const [id, setId] = useState("");
const [title, setTitle] = useState("");
const [text, setText] = useState("");
const [mode, setMode] = useState("");
useEffect(() => {
if (location.state === null) {
navigate("/", { replace: true });
} else {
location.state.id !== id && setId(location.state.id);
location.state.title !== title && setTitle(location.state.title);
location.state.text !== text && setText(location.state.text);
location.state.mode !== mode && setMode(location.state.mode);
}
}, [location.state]);
const handleTitleChange = (event) => {
setTitle(event.target.value);
};
const handleSave = () => {
edit(id, title, text);
navigate("/", { replace: true });
};
const handleCancel = () => {
if (mode === "remove-on-cancel") {
remove(id);
}
navigate("/", { replace: true });
};
return (
<Container>
<Stack spacing="lg">
<TextInput
placeholder="Your note's title"
label="Title"
withAsterisk
value={title}
onChange={handleTitleChange}
/>
<RichTextEditor
id="rte"
defaultValue={"Your note's text"}
value={text}
onChange={setText}
/>
<Group position="center" spacing="xl" grow>
<Button variant="subtle" onClick={handleCancel}>
Cancel
</Button>
<Button variant="default" onClick={handleSave}>
Save
</Button>
</Group>
</Stack>
</Container>
);
}
export default Edit;
Edit.propTypes = {
edit: PropTypes.func.isRequired,
remove: PropTypes.func.isRequired,
};
Next, we are going to update the components/Note.jsx
file as follows:
- <Accordion.Panel>{note.text}</Accordion.Panel>
+ <Accordion.Panel>
+ <div dangerouslySetInnerHTML={{ __html: note.text }}></div>
+ </Accordion.Panel>
The dangerouslySetInnerHTML
allows you to insert note.text
as an HTML inside <Accordion.Panel>
instead of a string. We need this since the rich text editor saves the note text as an HTML.
Run the app and observe how it works now.