Description
Affected Packages
"@tiptap/extension-bullet-list": "^2.3.0", "@tiptap/extension-color": "^2.3.0", "@tiptap/extension-document": "^2.3.0", "@tiptap/extension-heading": "^2.3.0", "@tiptap/extension-highlight": "^2.3.0", "@tiptap/extension-image": "^2.3.0", "@tiptap/extension-link": "^2.3.0", "@tiptap/extension-list-item": "^2.3.0", "@tiptap/extension-ordered-list": "^2.3.0", "@tiptap/extension-paragraph": "^2.3.0", "@tiptap/extension-placeholder": "^2.3.0", "@tiptap/extension-text": "^2.3.0", "@tiptap/extension-text-align": "^2.3.0", "@tiptap/extension-text-style": "^2.3.0", "@tiptap/extension-underline": "^2.3.0", "@tiptap/pm": "^2.3.0", "@tiptap/react": "^2.3.0", "@tiptap/starter-kit": "^2.3.0",
Version(s)
2.3.0
Bug Description
I have my editor as a component. And to the right of it is a list of words (This is a separate component from the editor, not a child).
And when I click on a word from the list, I want to see it highlighted. When I click on another word, it's another.
That is, every time the selectedKeyword changes, the function that makes the decorations should be triggered.
import React from 'react';
import { useSelector } from 'react-redux';
import { Extension } from '@tiptap/core';
import { Decoration, DecorationSet } from '@tiptap/pm/view';
import { EditorProvider } from '@tiptap/react';
import { debounce } from 'lodash';
import useUpdateEditorContent from './hooks/useUpdateEditorContent';
import TipTapEditorSettings from './TipTapEditorSettings';
import EditorToolbar from './toolbar/EditorToolbar';
import EditLinkContent from './toolbar/buttons/content/EditLinkContent';
import { tiptapEditorExtensions } from './extentions/tiptapEditorExtentions';
import { Plugin } from '@tiptap/pm/state';
import { selectSelectedKeyword } from '../../pages/contentOptimizer/contentPage/store/contentOptimizerContent.selectors';
import './TipTapEditor.scss';
const TipTapEditor = () => {
const [handleUpdateEditor] = useUpdateEditorContent();
const handleEditorChange = debounce((editorOnChangeData) => {
const { editor } = editorOnChangeData;
const updatedEditorData = editor?.getHTML();
const updatedEditorText = editor?.getText();
handleUpdateEditor(updatedEditorData, updatedEditorText);
}, 1000);
const selectedKeyword = useSelector(selectSelectedKeyword);
const getHighlightedKeywords = (doc) => {
const decorations = [];
doc.descendants((node, position) => {
if (!node.text) {
return;
}
if (selectedKeyword) {
const matchedKeywordKey = selectedKeyword?.regex
? selectedKeyword?.regex
: selectedKeyword?.keyword;
Array.from(
node.text.toLowerCase().matchAll(matchedKeywordKey)
).forEach((match) => {
const word = match[0];
const index = match.index || 0;
const from = position + index;
const to = from + word.length;
const decoration = Decoration.inline(from, to, {
class: `highlight-keyword selected-keyword`,
});
decorations.push(decoration);
});
}
});
return DecorationSet.create(doc, decorations);
};
const getHighlightKeywordsExtension = (getHighlightedKeywords) => {
if (!getHighlightedKeywords) return null;
return Extension.create({
name: 'colorHighlighter',
addProseMirrorPlugins() {
return [
new Plugin({
state: {
init(_, { doc }) {
return getHighlightedKeywords(doc);
},
apply(transaction, oldState) {
return transaction.docChanged
? getHighlightedKeywords(transaction.doc)
: oldState;
},
},
props: {
decorations(state) {
return this.getState(state);
},
},
}),
];
},
});
};
return (
<EditorProvider
slotBefore={<EditorToolbar />}
extensions={[
...tiptapEditorExtensions,
getHighlightKeywordsExtension(getHighlightedKeywords),
]}
onUpdate={handleEditorChange}
>
<TipTapEditorSettings />
<EditLinkContent />
</EditorProvider>
);
};
export default TipTapEditor;
Browser Used
Chrome
Code Example URL
Expected Behavior
Actual result:
<p>First Edition</p>
Expected result
<p><span class="highlight-keyword selected-keyword">First Edition</span></p>
Additional Context (Optional)
No response
Dependency Updates
- Yes, I've updated all my dependencies.
Metadata
Metadata
Assignees
Type
Projects
Status