#reactjs #react-quill
Вопрос:
Я использую react quill в качестве текстового редактора, и я использовал quill mention для добавления хэштегов и упоминаний людей в редакторе. Я просмотрел документы quill mention, но нет примера добавления ссылок на вставленный «хэштег» или «упоминание».
Для добавления ссылки есть prop, «linkTarget», но нет примера добавления ссылки к хэштегу и упоминанию.
Хэш-значения и atvalues из базы данных:
hashvalues:[{
id:1,
value:"newHashtag"
}]
atvalues:[{
id:1,
value:"Jhon"
}]
Итак, мой ожидаемый результат:
для хэштега:
<a href:`/#/hashtags/${id}`>#{value}</a>
для упоминания людей:
<a href:`/#/people/${id}`>@{value}</a>
Вот мой код для текстового редактора и модуля упоминания:
import React, { useEffect, useState } from "react";
import ReactQuill, { Quill } from "react-quill";
import * as Emoji from "quill-emoji";
import "react-quill/dist/quill.snow.css";
import "quill-emoji/dist/quill-emoji.css";
import "quill-mention/dist/quill.mention.css";
import "quill-mention";
//Add https to link if https is not present
const Link = Quill.import("formats/link");
Link.sanitize = function (url) {
// quill by default creates relative links if scheme is missing.
if (!url.startsWith("http://") amp;amp; !url.startsWith("https://")) {
return `http://${url}`;
}
return url;
};
Quill.register(Link, true);
Quill.register("modules/emoji", Emoji);
// Add sizes to whitelist and register them
const Size = Quill.import("formats/size");
Size.whitelist = ["extra-small", "small", "medium", "large"];
Quill.register(Size, true);
// Add fonts to whitelist and register them
const Font = Quill.import("formats/font");
Font.whitelist = [
"arial",
"comic-sans",
"courier-new",
"georgia",
"helvetica",
"lucida",
];
Quill.register(Font, true);
let atValues = [];
let hashValues = [];
const mention = {
allowedChars: /^[A-Za-zsÅÄÖåäö]*$/,
mentionDenotationChars: ["@", "#"],
linkTarget:"https://www.google.com",
source: function (searchTerm, renderList, mentionChar, ) {
let values;
if (mentionChar === "@") {
values = atValues;
} else {
values = hashValues;
}
if (searchTerm.length === 0) {
renderList(values, searchTerm);
} else {
const matches = [];
for (let i = 0; i < values.length; i )
if (~values[i].value.toLowerCase().indexOf(searchTerm.toLowerCase()))
matches.push(values[i]);
renderList(matches, searchTerm);
}
},
};
function Editor(props) {
const [editorHtml, setEditorHtml] = useState("");
const handleChange = (html) => {
setEditorHtml(html);
props.changeHandler(html);
};
useEffect(() => {
if (props.value) {
setEditorHtml(props.value);
} else {
setEditorHtml("");
}
if(props.values){
let hash=props.values
hash.map((v) => {
v["value"] = v["display"]
})
hashValues=hash
}
if(props.people){
let peoples = props.people
peoples.map((v) => {
v["value"] = v["display"]
})
atValues=peoples
}
}, [props.value]);
return (
<div>
<ReactQuill
onChange={handleChange}
value={editorHtml}
modules={modules}
formats={formats}
bounds={".app"}
placeholder={props.placeholder}
/>
</div>
);
}
const modules = {
toolbar: [
[{ header: [1, 2, 3, 4, 5, 6, false] }],
[{ list: "ordered" }, { list: "bullet" }],
["bold", "italic", "underline"],
[{ color: [] }, { background: [] }],
// [{ script: 'sub' }, { script: 'super' }],
[{ align: [] }],
["link", "blockquote", "emoji"],
["clean"],
],
clipboard: {
// toggle to add extra line breaks when pasting HTML:
matchVisual: false,
},
mention,
"emoji-toolbar": true,
"emoji-textarea": false,
"emoji-shortname": true,
};
const formats = [
"header",
"font",
"size",
"bold",
"italic",
"underline",
"strike",
"blockquote",
"list",
"bullet",
"indent",
"link",
"mention",
"emoji",
];
export default function EMTextArea({
placeHolder,
name,
value,
changeHandler,
hash,
peopleMention
}) {
return (
<div className="custom-toolbar-example">
<Editor
placeholder={placeHolder}
name={name}
value={value}
changeHandler={changeHandler}
values={hash}
people={peopleMention}
/>
</div>
);
}
Как я могу этого добиться?
Спасибо!
Ответ №1:
Я решил это, мне пришлось добавить ключ «link» в массив объектов atvalues и hashvalues.
Новые хэш-значения:
hashvalues:[{
id:1,
value:"hashtag",
link:"/#/users/hashtags/1"}]
И в модуле упоминания:
const mention = {
allowedChars: /^[A-Za-zsÅÄÖåäö]*$/,
mentionDenotationChars: ["@", "#"],
linkTarget: '_self',
source: function (searchTerm, renderList, mentionChar, ) {
let values;
if (mentionChar === "@") {
values = atValues;
} else {
values = hashValues;
}
if (searchTerm.length === 0) {
renderList(values, searchTerm);
} else {
const matches = [];
for (let i = 0; i < values.length; i )
if (~values[i].value.toLowerCase().indexOf(searchTerm.toLowerCase()))
matches.push(values[i]);
renderList(matches, searchTerm);
}
},
};
В любом случае, спасибо.
Комментарии:
1. Как вы думаете, вы можете помочь мне с этой функцией? Я пытаюсь реализовать это в своем приложении, но это вызывает проблемы. Я также использую NextJS….