Open bryceosterhaus opened 8 years ago
This has come up a handful of times. I think it would be reasonable to provide SelectionState
to decorator strategies, especially since people have requested being able to decorate selected ranges.
I'd love this as well.
I want to apply a decorator /only/ when the cursor is within the block of text. The problem I'm encountering is it's always a keystroke behind. Certain corner cases like backspacing (index is 0 when its actually 1, 1 when its actually 0) when I attempt to use getSelection() are impossible to figure out.
Is there a workaround?
I know its been 3 years. Did you find any decent work arounds? @butchmarshall or @hellendag.
I have a similar use case to @butchmarshall and ran into similar issues.
Alright I solved this with patch-package. Here is the relevant diff. (It is a little messy but its not on master yet 😅.
The general idea is anywhere we call decorator.getDecorations
we want to pass in the new SelectionState
as an extra parameter. I thought of setting the new SelectionState
on the contentState as selectionAfter
but I think that would potentially break things.
getDecorations
is called in regenerateTreeForNewDecorator
, regenerateTreeForNewBlocks
, and generateNewTreeMap
. I modified each of those functions to accept a new parameter newSelection
.
Those functions are called in two places. EditorState.set
and EditorState. create
. In EditorState.create
we don't have an existing selection so I just call generateNewTreeMap
with SelectionState.createEmpty()
. In EditorState.set
we either have a new selection in put.selection
or we can use the existing selection from EditorState.getSelection()
. I get the new or existing selection using var newSelection = put.selection || editorState.getSelection();
then pass that to the three methods I mentioned.
Finally the CompositeDraftDecorator needs to be modified to pass the newSelection parameter to the getDecorations method. That is straightforward.
If you are using DraftJS-Plugins you also need to modify the MultiDecorator to pass the newSelection parameter to the composed decorators.
This change enables a lot of really cool decorators which really on the position of the selection. Unfortunately since decorators are only called when content changes these are mostly useless. I don't think this should be added to draft-js but wanted to document the solution just in case anyone else got stuck here.
It would be nice for developers to be able to get the selectionState within a decorator strategy. When trying to do this with
this.state.editorState.getSelection()
inside of the decorator, the data seems to be out of sync.Try creating a decorator with this strategy
You will notice that
contentBlockText
will be one character(or keystroke) ahead ofeditorStateText
when typing.Does getting an up-to-date selectionState within the decorator strategy seem like a good idea?