question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

How to focus an inserted atomic block?

See original GitHub issue

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

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:3
  • Comments:5

github_iconTop GitHub Comments

2reactions
johnsonthedevcommented, May 15, 2020

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

1reaction
xander-adkinscommented, May 14, 2020

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.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to autofocus atomic block in draft js - Stack Overflow
I solved this problem. Carefully read selection state spec. So, basically, we need anchor (or start) and focus (or end).
Read more >
Atomic Blocks - SQL Server | Microsoft Learn
Atomic blocks are executed (atomically) within the transaction. Either all statements in the block succeed or the entire block will be rolled ...
Read more >
Atomic Blocks Plugin Help File
The easiest way is to click the (+) icon where you would like to add the new block, as seen in the screenshot...
Read more >
How to Make a Hero Image Modal Block Using Atomic CSS
“Atomic is a mobile-first, layout-focused, CSS library based on Tachyons for use ... which will combine Atomic CSS and Aphrodite styles and insert...
Read more >
Microsoft Loop components and atomic collaboration
But let's focus on the components for now. Loop Components are like molecules, and the blocks inside them are like atoms.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found