Do you want to request a feature or report a bug?
Feature.
I'm happy to open a PR with this change however I first wanted to see if there was interest in this from the Draft team.
What is the current behavior?
DOM Selections are cleared on blur.
What is the expected behavior?
DOM Selections are maintained.
I hoped to find a config option to disable this behaviour but there was no none.
Which versions of Draft.js, and which browser / OS are affected by this issue? Did this work in previous versions of Draft.js?
All versions.
In the Draft source there's this function and code comment,
function editOnBlur(editor, e) {
// In a contentEditable element, when you select a range and then click
// another active element, this does trigger a `blur` event but will not
// remove the DOM selection from the contenteditable.
// This is consistent across all browsers, but we prefer that the editor
// behave like a textarea, where a `blur` event clears the DOM selection.
// We therefore force the issue to be certain, checking whether the active
// element is `body` to force it when blurring occurs within the window (as
// opposed to clicking to another tab or window).
if (getActiveElement() === document.body) {
var _selection = global.getSelection();
var editorNode = editor.editor;
if (_selection.rangeCount === 1 && containsNode(editorNode, _selection.anchorNode) && containsNode(editorNode, _selection.focusNode)) {
_selection.removeAllRanges();
}
}
In our web app we have a toolbar outside the <Editor> for formatting, and this toolbar has both <button>s and <select>s.
The <select>s are the problem in Draft.js because clicking them visibly deselects any text. Have a look at https://jsfiddle.net/y4Lszjv5/ and type some text, select it (while making sure that the selection would be visible with the native <select> expanded) and the selection will disappear while the <select> is expanded. This makes it harder to see which text would be formatted.
Note that Quill and most other editors don't have this problem as they leave the consistent browser behaviour as-is (as your code comment notes _"This is consistent across all browsers"_).
So I guess there are two potential solutions,
_selection.removeAllRanges();, or<select> specifically and don't run _selection.removeAllRanges(); when focus has moved to that type of element.I think the best move here is to make this configurable. I can't promise I'll look into this right away since I'm quite busy at the moment (work and personal todos piling up 馃槄), but I'd be happy to either review a PR or look into this in a couple of weeks.
I'm also fine with the proposal as long as we preserve the current behavior as default. This could also have significant accessibility impact so this change would have to be verified to be friendly to screen readers.
Most helpful comment
I think the best move here is to make this configurable. I can't promise I'll look into this right away since I'm quite busy at the moment (work and personal todos piling up 馃槄), but I'd be happy to either review a PR or look into this in a couple of weeks.