<aside> 📄 모헤윰의 에디터 만들기 시리즈 모아보기 에디터 만들기 - ContentEditable [1/3] 에디터 만들기 - getSelection [2/3] 에디터 만들기 - Markdown [3/3]

</aside>

모헤윰의 핵심 기능 중 하나는 마크다운 서식 지원입니다. 왜 SNS에 마크다운을 끼얹을 생각을 했나 생각해보면 최초 기획부터 있다가 기능 다이어트를 한 후 살아남았기 때문인데, 아무튼 드디어 때가 왔습니다.

내부적으로 에디터를 외부 라이브러리를 사용하는게 좋지 않겠냐는 이야기가 나왔는데요, 결국 직접 구현해 보기로 했지만 그 과정에서 여러 레퍼런스를 얻을 수 있었습니다. 개인적으로 멋있다고 생각한 사이트 두 가지를 소개합니다.

HackMD - Collaborative Markdown Knowledge Base

Editor

Toast-UI 에디터는 노션에 임베디드로 넣으면 편집기가 나오네요;;

👀 레퍼런스 살펴보기

Untitled

놀랍게도 우리가 사용하는 에디터 중 textareainput 태그를 사용하는 경우는 거의 없습니다. 기껏해야 깃허브의 에디터가 textarea로 되어 있던 기억이 나네요. textarea의 가장 큰 문제는 입력 칸 안에 서식을 적용할 수 없다는 점이 되겠습니다. 다시 말해, syntax highlighting이 불가능합니다. 제가 아는 한에서는요.

그 문제를 우리는 div 태그에 contenteditable 속성을 통해 해결할 수 있습니다. contenteditabledivtextarea처럼 사용할 수 있게 해주며, 중간에 span같은 태그로 부분 스타일 적용이 가능합니다.

<aside> 💡 contenteditable을 적용하면 아래와 같은 메시지가 나타납니다.

A component is contentEditable and contains children managed by React. It is now your responsibility to guarantee that none of those nodes are unexpectedly modified or duplicated. This is probably not intentional.

이는 contenteditable이 적용된 태그는 사용자의 입력에 따라 새 element가 늘기도 하고, 다시 줄어들기도 하기 때문에 React 엔진이 관리할 수 없으니 그로 인한 부작용은 너 알아서 해라 라고 말하는 메시지입니다. 이 element를 더 이상 React가 지켜줄 수 없다는 경고인데요, contenteditable 속성이 적용된 태그에 suppressContentEditableWarning 속성을 같이 달아주면 비활성화됩니다.

</aside>

💪 시작해보자

그럼 이제 간단하게 contenteditable을 만들어 보겠습니다.

<div>
  <div>Toolbar</div>
  <div contentEditable>content</div>
  <div>
    <button type="button" onClick={submitHandler}>
      submit
    </button>
  </div>
</div>

Untitled

Untitled

오.. 잘 됩니다. 왜 될까요?

개발자 도구로 까보니 개행 입력을 할 때마다 div 태그가 새로 생성되어 그 안에 내용이 입력되고 있습니다. 이러면 contenteditable이 걸린 div를 참조하여 innerText, innerHTML중 한 쪽을 선택해서 가져다가 사용하면 될 것 같습니다.

contenteditable이 걸린 div에 css로 display: inline-block; 속성을 주면 개행이 br태그로 나눠진다고 하네요. 지금 저는 syntax highlight 기능까지 욕심을 내고 있기 때문에 부분 스타일 적용이 비교적 편해 보이는 div를 선택했습니다.