[javascript] Draft.js에서 텍스트 에디터의 인용구 기능 구현하기

Draft.js는 React 기반으로 구축된 텍스트 에디터 라이브러리로, 많은 기능들을 지원하고 있습니다. 이번에는 Draft.js를 사용하여 인용구 기능을 구현하는 방법에 대해 알아보겠습니다.

목차

Draft.js란?

Draft.js는 Facebook에서 개발한 텍스트 에디터 라이브러리로, React 기반으로 작동합니다. 풍부한 기능과 유연성을 제공하는 Draft.js를 사용하면 강력한 텍스트 에디터를 손쉽게 구현할 수 있습니다.

인용구 기능 구현하기

이제 Draft.js를 사용하여 텍스트 에디터에 인용구 기능을 추가하는 방법을 알아보겠습니다.

1. 인용구 블록 추가하기

Draft.js 에디터 내에서 인용구 블록을 추가하는 기능을 구현하는 첫 번째 단계입니다. 인용구 블록은 기존의 텍스트 블록과 다른 스타일을 적용하여 나타낼 수 있습니다.

import { EditorState, RichUtils } from 'draft-js';

// 인용구 블록 추가 함수
const addBlockquote = (editorState) => {
  const contentState = editorState.getCurrentContent();
  const selectionState = editorState.getSelection();
  const blockquoteContent = contentState.createEntity('blockquote', 'IMMUTABLE', {});
  const blockquoteEntityKey = blockquoteContent.getLastCreatedEntityKey();
  const newContentState = Modifier.insertText(contentState, selectionState, ' ', null, blockquoteEntityKey);
  const newEditorState = EditorState.push(editorState, newContentState, 'insert-characters');
  return EditorState.forceSelection(newEditorState, editorState.getSelection());
};

// 인용구 블록 추가 후 에디터 상태 업데이트
const handleAddBlockquote = () => {
  const newEditorState = addBlockquote(editorState);
  setEditorState(newEditorState);
};

위의 예시 코드는 인용구 블록을 추가하는 addBlockquote 함수와 해당 함수를 호출하여 에디터 상태를 업데이트하는 handleAddBlockquote 함수를 보여줍니다.

2. 인용구 스타일 적용하기

인용구 블록을 적용하는 것만으로는 사용자가 인용구를 구분할 수 없기 때문에, 스타일을 적용하여 시각적으로 구분해야 합니다. Draft.js에서는 인용구 블록에 스타일을 적용하는 방법이 제공됩니다.

const blockquoteStyle = {
  borderLeft: '2px solid #ddd',
  paddingLeft: '10px',
  marginLeft: '0',
  color: '#666',
};

// 커스텀 인용구 블록 렌더링 함수
const blockquoteBlockRenderer = (contentBlock) => {
  const type = contentBlock.getType();
  if (type === 'blockquote') {
    return {
      component: CustomBlockquoteComponent, // 인용구 컴포넌트
      editable: true,
      props: {
        style: blockquoteStyle, // 인용구 스타일
      },
    };
  }
};

// 인용구 컴포넌트
const CustomBlockquoteComponent = (props) => {
  return (
    <div style={props.style}>
      {props.children}
    </div>
  );
};

// 에디터에 커스텀 인용구 블록 렌더링 함수 등록
const blockRenderMap = Immutable.Map({
  'blockquote': {
    element: 'blockquote',
    wrapper: <CustomBlockquoteComponent />,
  },
});

const extendedBlockRenderMap = DefaultDraftBlockRenderMap.merge(blockRenderMap);

// 에디터 컴포넌트에서 BlockRenderMap 설정
const MyEditor = () => {
  return (
    <Editor
      blockRenderMap={extendedBlockRenderMap}
    />
  );
};

위의 예시 코드에서는 스타일이 적용된 커스텀 인용구 블록을 렌더링하는 CustomBlockquoteComponent를 구현하고, 해당 컴포넌트를 사용하여 인용구 블록을 랜더링하는 blockquoteBlockRenderer 함수를 구현한 후 에디터에 등록합니다.

3. 인용구 블록 제거하기

인용구 기능을 구현할 때, 인용구 블록을 제거하는 기능도 필요할 수 있습니다. Draft.js에서는 인용구 블록을 제거하는 기능이 간편하게 제공됩니다.

// 인용구 블록 제거 함수
const removeBlockquote = (editorState) => {
  const contentState = editorState.getCurrentContent();
  const selectionState = editorState.getSelection();
  const blockKey = selectionState.getStartKey();
  const blockData = contentState.getBlockForKey(blockKey).getData();
  if (blockData.get('blockquote')) { // 인용구 블록이면
    const newBlockData = blockData.delete('blockquote');
    const newContentState = contentState.setIn(['blockMap', blockKey, 'data'], newBlockData);
    return EditorState.push(editorState, newContentState, 'change-block-data');
  }
  return editorState;
};

// 인용구 블록 제거 후 에디터 상태 업데이트
const handleRemoveBlockquote = () => {
  const newEditorState = removeBlockquote(editorState);
  setEditorState(newEditorState);
};

위의 예시 코드에서는 인용구 블록을 제거하는 removeBlockquote 함수와 해당 함수를 호출하여 에디터 상태를 업데이트하는 handleRemoveBlockquote 함수를 보여줍니다.

결론

이제 Draft.js를 사용하여 텍스트 에디터에 인용구 기능을 구현하는 방법을 알아보았습니다. 인용구 블록을 추가, 스타일 적용 및 제거하는 기능을 구현할 수 있으며, 이를 활용하여 응용 프로그램에 맞는 텍스트 에디터를 만들 수 있습니다.

참고자료