Make editor.storage aware of changes for the character count plugin #5649
-
Hello, I've made a little prototype using tiptap and it works like a charm. I'm a bit puzzled on how to update the character count plugin when typing in the editor. I've tried several things, like passing the whole editor to my update handler and trying to get the character count from the store but I always get the same value. I read the whole docs like several times and I could not find any examples. I just know this should be possible, am I missing something? Is there a easy way to tell the plugin to update the store without implementing a counter myself (I don't mind that but this plugin does already 99% of what I want) Thanks in advance |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 3 replies
-
Can you share some code? Storage by default is not going to be reactive, so it is up to you to force re-renders if that is what you need to display it in your UI. You can have a listener onUpdate or onTransaction & if the value is different than it previously was, you can force a re-render. If you are using react this would be as simple as using |
Beta Was this translation helpful? Give feedback.
-
@nperez0111 thank you for your quick reply. My react skills are a bit limited still... My tiptap component looks like this: const editor = useEditor({
...editorConfig,
onUpdate: ({ editor }) => {
handleOnUpdate(editor.getJSON());
},
});
return (
<>
{editor && <CharacterCountPlugin editor={editor} />}
<EditorContent editor={editor} />
{editor && (
<BubbleMenu editor={editor} tippyOptions={{ duration: 100 }}>
<BubbleMenuBar editor={editor} />
</BubbleMenu>
)}
</>
);
}; And I've made a character count plugin like this: const CharacterCountPlugin = ({ editor }: { editor: Editor }) => {
if (!editor) return;
return (
<>
<Flex align="center" justify="center" gap="3">
<Text color="gray" size="1">
{editor.storage.characterCount.characters()} chars
</Text>
<Separator orientation="vertical" />
<Text color="gray" size="1">
{editor.storage.characterCount.words()} words
</Text>
</Flex>
</>
);
}; In my page I render it: export function Editor() {
const [content, setContent] = useState<string | JSONContent>(
JSON.parse(LOREM_IPSUM_JSON) || ''
);
const handleOnChange = (output: SetStateAction<JSONContent>) => {
setContent(output);
console.log('from tiptap editor:', output);
};
return (
<Tiptap
initialContent={content}
onChange={(newContent) => handleOnChange(newContent)}
/>
);
} Could you give me a little hint on how and where I would use the |
Beta Was this translation helpful? Give feedback.
-
const CharacterCountPlugin = ({ editor }: { editor: Editor }) => {
const { characterCount, wordCount } = useEditorState({
editor,
selector: ctx => {
return {
characterCount: ctx.editor.storage.characterCount.characters(),
wordCount: ctx.editor.storage.characterCount.words(),
}
},
})
return (
<>
<Flex align="center" justify="center" gap="3">
<Text color="gray" size="1">
{characterCount} chars
</Text>
<Separator orientation="vertical" />
<Text color="gray" size="1">
{wordCount} words
</Text>
</Flex>
</>
);
}; Here is how you would pull the character count and word count |
Beta Was this translation helpful? Give feedback.
-
@nperez0111 Thank you. It took me a while to understand how this works but I think I've got it now. Funny thing is, yesterday I made a branch to test out React 19 and I totally forgot about that, once back on my main branch using React 18.3.1 things started to work like expected ;-) This hook is not really documented, well I could not find it. If someone could direct me on how to I'm more then willing to give back and help updating the docs. Secondly, React 19. I'm honest I'm not a React Guru. All seems to work fine except for this hook. Is supporting React 19 something that is being considered or perhaps already worked on? PS: reading your blog I see you live in Rotterdam... Cool, I was born and raised in R'dam South ;-) |
Beta Was this translation helpful? Give feedback.
Here is how you would pull the character count and word…