Draft-js-plugins: How to focus an inserted atomic block?

Created on 28 May 2018  路  4Comments  路  Source: draft-js-plugins/draft-js-plugins

Hello.

I'm building a plugin that creates an atomic block and renders a custom react component. The problem that I have is to focus the block recently inserted.

The scenario is as follows:

  1. The user clicks on a button located in the Side Toolbar.
  2. An atomic block is inserted.
  3. Using blockRendererFn, the plugin display a custom React component.
  4. The cursor is located at the end of the editor but not in the inserted block.

The custom React component contains an input where the user types. What I want is to focus that input after insert the atomic block.

This is the plugin definition:

export default ({ 
  theme = {},
  decorator = (component) => component,
  options = defaultOptions
} = {}) => {
  const Explorer = decorateComponentWithProps(decorator(DefaultExplorer), { theme });
  const pluginOptions = Object.assign({}, defaultOptions, options);

  return {
    blockRendererFn: (block, { getEditorState, setEditorState, setReadOnly }) => {
      if (block.getType() === ATOMIC) {
        const contentState = getEditorState().getCurrentContent();
        const entity = block.getEntityAt(0);

        if (entity && contentState.getEntity(entity).getType() === BLOCK_TYPE) {
          return {
            component: Explorer,
            editable: false,
            props: {
              getEditorState,
              setEditorState,
              setReadOnly,
              options: pluginOptions
            }
          }; 
        }
      }
      return null;
    },

    SideToolbarButton: decorateComponentWithProps(SideToolbarButton, {
      addBlock
    }),
    addBlock
  };
};

And this is the render function in the Custom component (DefaultExplorer.js)

    return (
      <div 
        className="draft-js-plugins-custom" 
        contentEditable={false} 
        tabIndex={1} 
        onBlur={this.onBlur} 
        onFocus={this.onFocus}>

        <div className="container">
          <input 
            ref={ref => this.input = ref} 
            value={this.state.query}
            onChange={this.onChange}
            onKeyPress={this.onKeyPress}
            placeholder={this.props.placeholder} />
        </div>
      </div>
    );

To insert the block (addBlock.js)

export default (editorState, blockType, data = {}) => { 
  const contentState = editorState.getCurrentContent();

  const contentStateWithEntity = contentState.createEntity(blockType, 'IMMUTABLE', data);
  const entityKey = contentStateWithEntity.getLastCreatedEntityKey();

  const newEditorState = AtomicBlockUtils.insertAtomicBlock(
    editorState,
    entityKey,
    ' '
  );

  return EditorState.forceSelection(
    newEditorState,
    newEditorState.getCurrentContent().getSelectionAfter()
  );
};

ContentState
raw

Editor
blocks

stale

All 4 comments

Did you find any solution? I stucked here also. I added an image and i couldn't focus to it.

Did you find any solution? I stucked here also. I added an image and i couldn't focus to it.

This solution here helped me set focus states between editor and custom block for my own project. I don't know if this is the best solution, but it works.

hey, I am the creator of the snipped. Glad I could help others with it. I am new to draft.js as well so can't say anything about the implementation but it worked for me too :-)

I ended up with my own hook so I can assign it to any atomic block or decorator. I wrapped my images in a div with tabindex to make it focusable and to use overlay buttons for editing or cropping actions .

Also I created keyBindingFn and handleKeyCommand to navigate between the elements via arrow keys or detect deletion commands.

It was quite heavy. if you need an easier solution I suggest looking at this plugin: https://www.draft-js-plugins.com/plugin/focus

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Was this page helpful?
0 / 5 - 0 ratings