reactjswysiwygdraftjsreact-draft-wysiwygdraft-js-plugins

Not able to select text in react-draft-wysiwyg rich text editor


I'm facing an issue in my React version(react: ^18.2.0,) application where I'm using the react-draft-wysiwyg rich text editor. The problem is that I'm unable to select text within the editor. Basically am working on react flow (reactflow: ^11.9.",)

React flow provides a pane/playground to which we can move by grabbing, When My Editor opens the actual behavior of the editor when cursor is inside rich text editor am able to grab the text editor and not able to select the text written in it,

I tried by giving z-index to my Editor adding some css like

cursor: text !important;
user-select: text !important;

Here is component code

import { Icon } from '@iconify/react';
import { EditorState } from 'draft-js';
import { Editor } from 'react-draft-wysiwyg';
import { convertToHTML } from 'draft-convert';
import {stateFromHTML} from 'draft-js-import-html';

import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css';

// eslint-disable-next-line react/display-name
const TextBody = React.forwardRef((props, ref) => {
  const {comp, components, setComp, type} = props;
  const [convertedContent, setConvertedContent] = useState(comp.props.value === 'Add something here' ? '' : comp.props.value);
  let contentState = stateFromHTML(convertedContent);
  const [editorState, setEditorState] = useState(() => EditorState.createWithContent(contentState));
  useEffect(() => {
    let html = convertToHTML(editorState.getCurrentContent());
    setConvertedContent(html);
  }, [editorState]);

  useEffect(() => {
    const arr = components?.map((item) => {
      if (item.order === comp.order) {
        item.props = {
          ...item.props,
          value: convertedContent
        }
      }
      return item
    });
    setComp(arr);
  }, [convertedContent]);

  const deleteNode = () => {
    if (components.length === 1) {
      alert("Node should contain atleast 1 widget!");
      return;
    }
    const newData = components.filter((data) => data.order !== comp.order);
    setComp(newData);
  }
  
  useEffect(() => {
    if (ref) {
      ref.current.focusEditor();
    }
  }, [ref]);

  return(
    <>
      <Box
          display="flex"
          justifyContent="space-between"
      >
        <Box
            width="93%"
            // position={"relative"}
            // zIndex={"9999999"}
        >
          <Editor
          editorStyle={{ zIndex: 9999 }}
              editorClassName="editor-class"
              editorState={editorState}
              onEditorStateChange={setEditorState}
              placeholder="Add text here"
              ref={ref}
              toolbar={{
                  image: {
                    alt: { present: true, mandatory: false },
                    previewImage: true,
                    inputAccept: 'svg',
                  },
                  options: ['inline', 'link'],
                  inline: {
                    inDropdown: false,
                    options: ['bold', 'italic', 'underline', 'strikethrough'],
                  },
                  link: {
                    inDropdown: false,
                    options: ['link'],
                  },
                }}
              toolbarClassName="toolbar-class"
              toolbarCustomButtons={[
                <div style={{
                  display: 'flex',
                  alignItems: 'center'
                }}
                >
                  <div
                      className="insert-entity"
                      onClick={() => alert('Coming Soon!')}
                  >
                    Insert Entity
                  </div>
                </div>,
                ]}
              wrapperClassName="wrapper-class"
          />
        </Box>

        <Box
            cursor="pointer"
            onClick={() => deleteNode()}
        >
          <Icon
              color='hsla(0, 0%, 85%, 1)'
              icon="ic:outline-delete"
          />
        </Box>
      </Box>

      <Box marginTop="10px">
        <Checkbox
            color="text.body"
            iconColor='blue.400'
            iconSize='1rem'
            onChange={() => alert('Coming Soon!')}
        >
          Question
        </Checkbox>
      </Box>

      {type === "customer_response_node" ? <>
        <Box
            marginTop="10px"
            width="93%"
        >
          <Text
              color="text.body"
              fontSize="xs"
          >
            Triggered Intent
          </Text>

          <Input
              borderRadius="0.3125rem"
              placeholder="Intent Name"
              size="sm"
          />
        </Box>

        <Box
            marginTop="10px"
            width="93%"
        >
          <Text
              color="text.body"
              fontSize="xs"
          >
            Add Entity
          </Text>

          <Input
              borderRadius="0.3125rem"
              placeholder="Entity name"
              size="sm"
          />
        </Box>
      </> : null}

      <Divider
          borderColor="#D8D8D8"
          marginTop="10px"
          width="93%"
      />                

      <Box
          display="flex"
          justifyContent="right"
          marginTop="10px"
          width="93%"
      >
        <Button
            _hover={{ backgroundColor: 'primary.90' }}
            backgroundColor="primary.100"
            color="white"
            onClick={() => alert('Coming Soon!')}
            size="sm"
            width="118px"
        >
          Add Variant
        </Button>
      </Box>
    </>
  )
});

export default TextBody;

Solution

  • It sounds like you're encountering a conflict between the behavior of the text editor implemented using Draft.js and the mouse interaction expected by the React Flow library. React Flow might be capturing the mouse events in a way that interferes with the normal behavior of Draft.js.

    In the Editor, you have customised toolbar too.

    All you need to do is to disable drag property via following nopan nodrag

    Add both classes in your editorClassName and toolbarClassName, you are good to go.