Do you want to request a feature or report a bug?
It is a feature.
What is the current behavior?
At the moment, there is no autoFocus property. There is only a focus() method on the editor itself.
What is the expected behavior?
I don't know if that's possible, but I think that an autoFocus property could be useful.
I'm proposing this because I'd like to focus the text editor, but I can't use (or don't know how) the focus method. My <Editor /> component is buried in multiple component layers, and I can't find a proper way to focus it.
Which versions of Draft.js, and which browser / OS are affected by this issue? Did this work in previous versions of Draft.js?
I'm using [email protected]
@antoinerey this is very simple problem at first look. If draft loses focus, it's changing state:
handleChange(editorState: EditorState): void {
if (!editorState.getSelection().getHasFocus()) {
editorState = EditorState.moveFocusToEnd(editorState);
}
this.setState({
editorState
});
}
But this code disallow any attempt to disable autoFocus. That's why I've added following code:
componentWillReceiveProps(nextProps: Props): void {
if (nextProps.autoFocus && !this.selecting) {
if (!this.focusTimeout) {
this.focusTimeout = setTimeout(() => {
this.focusTimeout = null;
this.focus(this.props.editorState);
}, 10);
}
} else if (this.focusTimeout) {
clearTimeout(this.focusTimeout);
this.focusTimeout = null;
}
}
Now you can switch to switch focus to other elements, but you have to disable autoFocus for your draft-js instance.
But this is not complete solution. User should be able to select something.
componentDidMount(): void {
if (this.props.autoFocus) {
this.focus(this.props.editorState);
}
document.addEventListener('mousedown', this.handleGlobalMouseDown, false);
document.addEventListener('mouseup', this.handleGlobalMouseUp, false);
}
handleGlobalMouseDown(): void {
this.selecting = true;
}
handleGlobalMouseUp(): void {
this.selecting = false;
const selection = document.getSelection();
if (!selection.toString() && this.props.autoFocus) {
this.focus(this.props.editorState);
}
};
componentWillUnmount(): void {
document.removeEventListener('mousedown', this.handleGlobalMouseDown, false);
document.removeEventListener('mouseup', this.handleGlobalMouseUp, false);
}
And here is the most interesting part. If user selected something, you can't get focus back. So you have to await until user will click again and selection will become empty.
I think this behaviour is completely depends application-specific, that's why this shouldn't be in core.
I'm not sure to understand your solution. What I suggested was the exact same behavior than the <input /> one.
<Editor autoFocus /> component is mounted<input autoFocus />That's it. Nothing more.
At the moment, I'm doing something like this :
componentDidMount() {
this.editor.focus()
}
// this.editor being the reference of the `<DraftEditor />` itself.
As far as I know, it works very well (maybe there is a subtle problem with this approach I'm not aware of), but an autoFocus property would be even simpler.
Do you understand what I'm suggesting ? 馃惞
I have the same use case. I noticed calling the DraftEditor's focus method in componentDidMount (just as you're doing above) can cause my Editor to have weird behaviors. editorState.getSelection().getHasFocus() will be true, but onFocus will not get called.
@antoinerey your solution doesn't work (anymore?) for me neither.
Any plan to add this? Not that it's critical, but it's really a good nice-to-have.
Most helpful comment
I have the same use case. I noticed calling the DraftEditor's
focusmethod incomponentDidMount(just as you're doing above) can cause my Editor to have weird behaviors.editorState.getSelection().getHasFocus()will betrue, butonFocuswill not get called.