Как реализовать drag and drop в редакторе текста с помощью draft-js?

Для реализации drag and drop в редакторе текста с использованием библиотеки Draft.js вам понадобится несколько шагов.

1. Добавьте необходимые зависимости в свой проект:

npm install draft-js react-dnd react-dnd-html5-backend

react-dnd - это библиотека для реализации функциональности перетаскивания элементов
react-dnd-html5-backend - это HTML5 бэкенд для react-dnd

2. Импортируйте необходимые компоненты и хуки в вашем редакторе:

import { Editor, EditorState } from 'draft-js';
import { useDrag, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';

3. Создайте компонент, который будет отображать перетаскиваемые блоки текста:

const DraggableBlock = ({ blockKey, children }) => {
  const [{ isDragging }, drag] = useDrag(() => ({
    item: { blockKey },
    collect: (monitor) => ({
      isDragging: monitor.isDragging(),
    }),
  }));

  return (
    <div ref={drag} style={{ opacity: isDragging ? 0.5 : 1 }}>
      {children}
    </div>
  );
};

4. Создайте компонент, обеспечивающий возможность перетаскивания и сброса блоков:

const DraggableEditor = () => {
  const [editorState, setEditorState] = useState(EditorState.createEmpty());
  
  const [{ canDrop, isOver }, drop] = useDrop(() => ({
    accept: 'block',
    drop: (item, monitor) => {
      const { blockKey } = item;
      // обработка события сброса блока в редакторе
    },
    canDrop: (item, monitor) => {
      // проверка на возможность сброса
      return true;
    },
    collect: (monitor) => ({
      canDrop: monitor.canDrop(),
      isOver: monitor.isOver(),
    }),
  }));

  return (
    <div ref={drop} style={{ backgroundColor: isOver && canDrop ? 'lightblue' : 'white' }}>
      <Editor
        editorState={editorState}
        onChange={setEditorState}
        blockRendererFn={blockRendererFn}
      />
    </div>
  );
};

5. Создайте функцию blockRendererFn, чтобы использовать компонент DraggableBlock для перетаскиваемых блоков:

const blockRendererFn = (contentBlock) => {
  const blockType = contentBlock.getType();
  if (blockType === 'unstyled') {
    return {
      component: DraggableBlock,
      editable: true,
    };
  }
};

6. Ваш редактор теперь готов к использованию перетаскиваемых блоков. Чтобы добавить блоки в редактор, вам необходимо создать компонент, который будет отображать эти блоки и обозначать их как перетаскиваемые:

const DraggableBlocks = () => {
  return (
    <div>
      <DraggableBlock blockKey="block1">
        <div>Перетаскиваемый блок 1</div>
      </DraggableBlock>
      <DraggableBlock blockKey="block2">
        <div>Перетаскиваемый блок 2</div>
      </DraggableBlock>
    </div>
  );
};

Вы можете разместить DraggableBlocks где угодно на странице, и блоки можно будет перетаскивать и сбрасывать в редакторе.

Обратите внимание, что данный пример демонстрирует базовую реализацию drag and drop в редакторе Draft.js с использованием библиотеки react-dnd. Вы можете дополнить его своей логикой и стилизацией в соответствии с вашими потребностями.