cantera cantera - 26 days ago 17
React JSX Question

Focus Editor, Position Cursor at Start of First Block

I need to apply focus to a Draft.js editor and position the cursor at the start of the first line/block. The editor contains multiple lines/blocks.

With only

this.refs.editor.focus()
being applied, the cursor is always positioned at the start of the second block/line within the editor.

Using this question and this issue as guides, I tried the code below without success. I suspect that passing
blockMap
to
createFromBlockArray()
is not correct:

focusTopLine() {

this.refs.editor.focus();

const { editorState } = this.state;
const contentState = editorState.getCurrentContent();
const selectionState = editorState.getSelection();
const blockMap = contentState.getBlockMap();

const newContentState = ContentState.createFromBlockArray(blockMap);
const newEditorState = EditorState.createWithContent(newContentState);

this.setState({
editorState: EditorState.forceSelection(newEditorState, selectionState)
});
}

Answer

You can (probably, I haven't tested this) do it similar to how EditorState.moveFocusToEnd() is implemented:

First, create a new EditorState where the first block is selected:

function moveSelectionToStart(editorState) {
  const content = editorState.getCurrentContent()
  const firstBlock = content.getFirstBlock()
  const firstKey = firstBlock.getKey()
  const length = firstBlock.getLength()

  return EditorState.acceptSelection(
    editorState,
    new SelectionState({
      anchorKey: firstKey,
      anchorOffset: length,
      focusKey: firstKey,
      focusOffset: length,
      isBackward: false,
    })
  )
}

Then use that to move the focus:

function moveFocusToStart(editorState) {
  const afterSelectionMove = EditorState.moveSelectionToStart(editorState)
  return EditorState.forceSelection(
    afterSelectionMove,
    afterSelectionMove.getSelection()
  )
}

It can now be used like this:

this.setState({ editorState: moveFocusToStart(editorState) })
Comments