Tab Behaviour

This plugin will be responsible of the behaviour of the tab key.

The tab behaivour should be: on tab press, current caret position should jump to the position of a special character defined by props ( · by default ).

On this plugin we will be using the onTab function, that triggers when the tab key is pressed, this function recieves the javascript event e and the Draft js plugins object obj.

First thing to do is preventing the default behaviour of the "tab" key.

And then getting the parameters we will be using to find the next position (if there is any)

const onTab = (e, obj) => {
      e.preventDefault();
      const editorState = obj.getEditorState();
      const contentState = editorState.getCurrentContent();
      const anchorOffset = editorState.getSelection().getAnchorOffset();
      const anchorKey = editorState.getSelection().getAnchorKey();

      // Find Next Position, and if there is any, do something
    };

Next we use the parameters we got to get the next position. For doing this, we look for the next character, or the first (if the caret position is beyond any character), from the next position we will be needing the anchorOffset and the anchorKey, to define which block and the position in the block.

const getNextPosition = (contentState, anchorOffset, anchorKey, char) => {
        const Text = contentState.getBlockForKey(anchorKey).getText();
        const slicedText = Text.slice(anchorOffset);

        if (contentState.getPlainText().indexOf(char) !== -1) {
        // if there is a char in all the terminal
          if (slicedText.indexOf(char) !== -1) {
          // if there is a char in the current content block
            return {
              anchor: slicedText.indexOf(char) + anchorOffset + 1,
              key: anchorKey,
            };
          } else if (contentState.getBlockAfter(anchorKey)) {
            // if there is a next content block
            return getNextPosition(contentState, 0, contentState.getBlockAfter(anchorKey).getKey(), char);
          }
          //if there is no next content block, goes back to the start
          const nextPosition = getNextPosition(contentState, 0,
            contentState.getBlocksAsArray()[0].getKey(), char);
          if (nextPosition.anchor !== anchorOffset) {
            // only returns something if there is a new position.
            return nextPosition;
          } return null;
        } return null;
      };

Then we check either if is a next position or not

if (nextPosition) {
     // Create a new SelectionState and set it
}

If there is a next position, we have to create a new selection state, that enables us to change the caret position.

In order to do that, we create an empty SelectionState, with a custom key, then we merge it with the anchorKey (that indicates the block we wish moving to) and the anchorOffset (that indicates the numeric position in our block).

const getNextSelectionState = (nextPosition) => {
  const selectionState = SelectionState.createEmpty('customSelectionState');
  return (
    selectionState.merge({
      anchorOffset: nextPosition.anchor,
      anchorKey: nextPosition.key,
    })
  );
};

At last we merge our custom SelectionState with the editorState, using the forceSelection function and the setEditorState function.

obj.setEditorState(EditorState.forceSelection(editorState, nextSelectionState));

results matching ""

    No results matching ""