Search code examples
reactjsdraftjs

How to enter text in a text-input inside an atomic block


I have an atomic block rendered in the following manner:

const blockRendererFn = (block) => {
    if (block.getType() === 'atomic') {
      return {
        component: (props) => (
          <AtomicBlockRenderer {...{
            ...props,
            getEditorState: () => editorState,
            setEditorState: (editorState) => dispatchSetEditorState(editorState),
            editorEl
          }}/>
        ),
        editable: true
      }; 
    }

    return null;
  };

const AtomicBlockRenderer = (props) => {
  const { contentState, block } = props;
  const entity = contentState.getEntity(block.getEntityAt(0));
  const type = entity.getType();

  switch (type) { 
    case 'video': return <VideoInput {...{...props, entity}} />;
    default: return null;
  }
};


import React, { useRef } from 'react';

export const VideoInput = (props) => {
  const inputEl = useRef(null);

  return (
    <div
      className="video-input"
    >
      <input
        ref={inputEl}
        type="text"
        className="form-control"
        placeholder="paste youtube or vimeo url"
      />
    </div>
  );  
};

I am not able to focus on the input element inside VideoInput. Even if I hook up focus somehow using ref, the editor crashes as my content-state becomes malformed. How can I set up the input element to receive URLs from users?

Sandbox: https://codesandbox.io/s/lucid-hypatia-61g3x


Solution

  • You need to switch the editor to read only mode when the user tries to interact with the input field. You can do that by adding an onFocus handler to the input field that sets the editor to read only.

    To demonstrate that this is what you need, try the following steps: * Add a video element * Open the React debugger and flip the readOnly flag to true on the DraftEditor component * Try to type something in the input field

    See https://draftjs.org/docs/api-reference-editor#readonly for further reference.