[javascript] Draft.js를 사용한 텍스트 에디터의 대화형 드로우 다이어그램(Flowchart) 기능 구현하기

드로우 다이어그램(Flowchart)은 비즈니스 프로세스, 소프트웨어 개발, 의사 결정 흐름 등을 시각적으로 표현하는 데 사용되는 강력한 도구입니다. 이번 기술 블로그에서는 Draft.js를 사용하여 텍스트 에디터에 대화형 드로우 다이어그램 기능을 구현하는 방법을 알아보겠습니다.

목차

  1. Draft.js 소개
  2. 드로우 다이어그램 기능 구현하기
    1. Draft.js 설치하기
    2. 드로우 다이어그램 라이브러리 선택하기
    3. Draft.js에 드로우 다이어그램 기능 통합하기
  3. 결론

Draft.js 소개

Draft.js는 페이스북에서 개발한 React 기반의 리치 텍스트 에디터 라이브러리입니다. React의 가상 DOM을 기반으로한 성능 최적화와 쉽고 유연한 API를 제공하여 사용자 친화적인 텍스트 에디터를 쉽게 개발할 수 있습니다.

드로우 다이어그램 기능 구현하기

Draft.js 설치하기

Draft.js를 사용하기 위해서는 먼저 프로젝트에 React와 ReactDOM을 설치해야 합니다. 이후 npm을 사용하여 Draft.js를 설치합니다.

npm install draft-js

드로우 다이어그램 라이브러리 선택하기

드로우 다이어그램을 구현하기 위해서는 텍스트 에디터 내에서 사용자가 그림을 그릴 수 있도록 하는 라이브러리가 필요합니다. 대표적인 라이브러리 중 하나인 Mermaid를 사용하여 드로우 다이어그램을 구현해보겠습니다.

Mermaid를 설치하기 위해 아래의 명령어를 실행합니다.

npm install mermaid

Draft.js에 드로우 다이어그램 기능 통합하기

Draft.js에서 드로우 다이어그램 기능을 구현하기 위해서는 Draft.js의 커스텀 블록(Block)을 사용해야 합니다. 이를 위해 Draft.jsContentBlock 클래스를 확장하고 드로우 다이어그램을 렌더링하는 컴포넌트를 작성합니다.

import React from 'react';
import { ContentBlock } from 'draft-js';

class FlowchartBlock extends ContentBlock {
  render() {
    const { contentState, block } = this.props;
    const text = contentState.getBlockMap().get(block.getKey()).getText();

    return (
      <div className="flowchart-block">
        {text}
      </div>
    );
  }
}

Draft.js의 커스텀 블록을 구현한 후, 해당 블록을 사용하여 텍스트 에디터에 드로우 다이어그램 기능을 추가할 수 있습니다.

import React, { useState } from 'react';
import { Editor, EditorState, RichUtils, getDefaultKeyBinding, KeyBindingUtil } from 'draft-js';
import mermaid from 'mermaid';
import FlowchartBlock from './FlowchartBlock';

function FlowchartEditor() {
  const [editorState, setEditorState] = useState(EditorState.createEmpty());
  
  const handleKeyCommand = (command) => {
    const newState = RichUtils.handleKeyCommand(editorState, command);
    if (newState) {
      setEditorState(newState);
      return 'handled';
    }
    return 'not-handled';
  };
  
  const keyBindingFn = (e) => {
    if (KeyBindingUtil.hasCommandModifier(e) && e.keyCode === 75) {
      return 'create-flowchart';
    }
    return getDefaultKeyBinding(e);
  };
  
  const handleFlowchartCommand = () => {
    const contentState = editorState.getCurrentContent();
    const contentStateWithEntity = contentState.createEntity(
      'flowchart',
      'IMMUTABLE',
      { value: 'flowchart' }
    );
    const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
    const newEditorState = EditorState.push(
      editorState,
      contentStateWithEntity,
      'apply-entity'
    );
    setEditorState(newEditorState);
  };
  
  const blockRendererFn = (contentBlock) => {
    const type = contentBlock.getType();
    if (type === 'flowchart') {
      return {
        component: FlowchartBlock,
        editable: false,
      };
    }
    return null;
  };
  
  const editorProps = {
    editorState,
    handleKeyCommand,
    keyBindingFn,
    blockRendererFn,
  };
  
  return (
    <div>
      <button onClick={handleFlowchartCommand}>Create Flowchart</button>
      <div className="editor">
        <Editor {...editorProps} />
      </div>
    </div>
  );
}

위의 코드에서 handleFlowchartCommand 함수는 사용자가 드로우 다이어그램을 생성하도록 하는 역할을 합니다. 사용자가 ‘Create Flowchart’ 버튼을 클릭하면, Draft.js의 EditorState에 새로운 드로우 다이어그램 블록을 추가합니다.

결론

이번 기술 블로그에서는 Draft.js를 사용하여 텍스트 에디터에 대화형 드로우 다이어그램 기능을 구현하는 방법을 알아보았습니다. Draft.js의 커스텀 블록을 사용하여 드로우 다이어그램을 렌더링하고, Mermaid 라이브러리를 통해 실제 다이어그램을 그릴 수 있었습니다. 이를 응용하여 다양한 상황에 맞는 텍스트 에디터를 개발할 수 있습니다.

더 자세한 내용은 Draft.js 공식 문서Mermaid 공식 문서를 참고하시기 바랍니다.