Reputation: 389
In react-contenteditable
, the html
attributes only accepts string
, how can I manage to add JSX element with eventlistener
with in the string.
import ContentEditable from "react-contenteditable";
import "./styles.css";
const text = "I want to order cheese chicken pizza.";
const Elems = {
cheese: (
<span style={{ color: "red" }} onClick={() => alert("clicked cheese span")}>
cheese
</span>
),
chicken: (
<span
style={{ color: "red" }}
onClick={() => alert("clicked chicken span")}
>
chicken
</span>
)
};
export default function App() {
const swapText = () => {
const text_array = text.split(" ");
console.log(text_array);
const a = text_array.map((item) => {
if (item in Elems) item = Elems[item];
else item += " ";
return item;
});
return a;
};
return (
<div className="App">
<h2>React contenteditable</h2>
<ContentEditable html={swapText()} />
</div>
);
}
Upvotes: 0
Views: 474
Reputation: 191976
You can convert react elements to markup using ReactDOMServer.renderToStaticMarkup(element)
. This would help with the styles, but not with the click handler:
if (item in Elems) item = renderToStaticMarkup(Elems[item]);
For the items to be clickable, you'll need to pass an onClick
handler to <ContentEditable>
component (or a parent of it):
<ContentEditable onClick={handleClick} html={swapText()} />
You would also need to identify the clickable elements. In this example, I've data-action
tags to both of them:
const Elems = {
cheese: (
<span style={{ color: 'red' }} data-action="cheese">
cheese
</span>
),
chicken: (
<span style={{ color: 'red' }} data-action="chicken">
chicken
</span>
)
};
The click handler searches the event target or a parent that has the data-action
tag using Element.closest()
, if it finds one it acts on the tags value:
const handleClick = (e) => {
const target = e.target.closest('[data-action]');
if (!target) return;
const action = target.dataset.action;
alert(action);
};
Working example - sandbox
Upvotes: 1