Looking for some clarification on decorators, entities and custom components.
Lets say every time a user types unicorn you'd like to replace the text with a new block containing a video of a unicorn.
It appears that with a decorator you can identify the word unicorn and have a component style it, like the tweet example. However, we want to replace the text with a custom block.
Is the right approach here to have the strategy handler of the decorator apply an entity to the text then have the custom block rendering function render the entity appropriately? If so, is there a role for the decorator component, or is it kind of a noop in this scenario?
Also, would be great to have an example that covers a similar use case (one that ties together decorators and custom block renderers).
Thanks!!
@skhavari - I apologize for the lack of direction/clarity in how to accomplish this. Semantically, my understanding is that decorators should decorate the text content, but not actually change make major changes to it. Like you could style it with CSS or add a tooltip, but it seems like you should leave the text content itself unchanged.
For this unicorn example, I think the more appropriate approach would be to create an entity when you see the word "unicorn", then the strategy handler of the decorator looks for and finds the entity (as opposed to looking for the "unicorn" text itself) and renders the picture of the unicorn.
I definitely agree that an example here would be valuable and have been working on writing some better introductory articles for getting started with Draft.
If anyone else has other thoughts, I'd love to hear them.
Thanks for the quick response @davidchang!
2 questions:
also if anyone knows of a nice example that covers this use case, would love to take a look.
Hi @skhavari
Not sure if this helps, but I ran into a similar issue where I needed to replace the text within a block based on a composite decorator's strategy. My use case was similar to the Emoji menu in draft-js-plugins (though mine is for spellchecking). I ended up using the data-offset-key on the decorated item to find and manipulate the text. Here is my method for replacing the text based on the offset-key. I adapted much of it from the Emoji sample in draft-js-plugins.
replaceWordAtOffsetKey = (newWord?:string, offsetKey?:string) => {
if(!newWord || !offsetKey) return;
const [blockKey, unparsedDecoratorKey, unparsedLeafKey] = offsetKey.split('-');
const decoratorKey = parseInt(unparsedDecoratorKey, 10);
const leafKey = parseInt(unparsedLeafKey, 10);
const { start, end } = this.state.editorState.getBlockTree(blockKey).getIn([decoratorKey, 'leaves', leafKey]);
const newSelectionState = this.state.editorState.getSelection().merge({
anchorKey: blockKey,
anchorOffset: start,
focusKey: blockKey,
focusOffset: end,
});
this.setState({
editorState: EditorState.push(
this.state.editorState,
Modifier.replaceText(
this.state.editorState.getCurrentContent(),
newSelectionState,
newWord))
});
};
Thanks @drewjenkins for helping out. Looks like this has been answered so I'm going to close this out.
Most helpful comment
Thanks for the quick response @davidchang!
2 questions:
also if anyone knows of a nice example that covers this use case, would love to take a look.