Это немного сложно объяснить, но мне нужно создать компонент React, где пользователь может выбрать текст и применить к нему «тег», который сделает текст жирным. Мне нужно записать положение тегов, так как эти данные должны храниться и использоваться в других системах, которым необходимо расположение тегов.
Сложная часть: пользователь может редактировать текст и применять перекрывающиеся теги.
Использование сущностей в DraftJS Я создал решение, которое поддерживает все, кроме перекрывающихся тегов, так как в DraftJS несколько сущностей не могут покрывать один и тот же фрагмент текста.
private readonly onTagTypeClicked = (tagType: ITagType) => {
const editorState = this.state.editorState;
const selection = this.state.selectionEditorState.getSelection();
if (!selection.isCollapsed()) {
const contentState = editorState.getCurrentContent();
const contentStateWithEntity = contentState.createEntity(
'TAG',
'MUTABLE',
{ tag: tagType }
);
const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
const newEditorState = EditorState.set(editorState, { currentContent: contentStateWithEntity });
this.setState({
editorState: RichUtils.toggleLink(newEditorState, newEditorState.getSelection(), entityKey)
});
}
}
Затем я попытался написать решение с нуля, используя div с контентом contentEditable и пользовательские теги, которые потерпели неудачу, поскольку html приводил к искаженному html, как показано ниже
<tag-1 class="tag">This is a <tag-2 class="tag">test</tag-1> of tagging</tag-2>
, который браузер будет пытаться исправить, что означает, что я не мог отслеживать теги.
Я пытался взломать, используя комментарии, чтобы обойти проблему разбора html:
<!--tag1--><b>This is a</b><!--tag2--><b>test<!--/tag1--> of tagging</b><!--/tag2-->
Комментарии продолжали исчезать, мешая этому подходу работать.
Я пытался сделать то же самое со SlateJS, но это оказалось сбоем, и комментарии продолжали исчезать.
public renderMark = (props: any, editor: any, next: any) => {
switch (props.mark.type) {
case 'bold':
return <strong {...props.attributes}> <ReactComment text={'Tag1'} />{props.children} <ReactComment text={'/Tag1'} /> </strong>;
default:
return next();
}
}
В идеале кто-нибудь знает о существующем компоненте, который может обрабатывать то, что я ищу, или надежном способе кодирования нестандартного решения?