본문 바로가기

javascript/react

[React-Quill] 에디터 영역 스크롤 바 만들기

react-quill 을 통해 에디터를 그대로 띄워보면 다음과 같다.

react-quill 기본 모습

기본 설정에서도 글을 작성하는데는 문제가 없지만, 에디터 영역이 너무 작다는 점은 불편하게 느껴진다. 특히 해당 영역은 기본적으로 스크롤 기반으로 동작하지 않기 때문에 글을 길게 작성함에 따라 에디터 영역이 계속 증가한다.

에디터 영역이 계속 증가하는 모습

 티스토리 블로그 글쓰기처럼 에디터 영역이 계속 확장되어도 상관 없다면 이 동작 그대로 사용해도 되지만, 나는 에디터 글쓰기 란이 어느 정도 초기 공간을 가지고 있고, 그 이상은 스크롤 형식으로 동작하기를 원하기 때문에 이 동작을 변경해야 한다.

 Quill 공식문서에서는 scollingController 옵션을 통해 스크롤 대상을 변경할 수 있다고 설명하고 있다.

https://quilljs.com/docs/configuration/#scrollingcontainer

 

Configuration - Quill

Configuration Quill allows several ways to customize it to suit your needs. This section is dedicated to tweaking existing functionality. See the Modules section for adding new functionality and the Themes section for styling. Container Quill requires a co

quilljs.com

공식 문서 기준으로, Quill의 스크롤 바를 가지는 기본 엘리먼트는 .ql-editor 클래스가 적용된 엘리먼트이다. 이 엘리먼트의 부모에 대해 높이를 고정하면 overflow-y: auto 옵션에 의해 스크롤 방식으로 동작할 수 있게 된다.

react-quill 기본 구조

 Quill 라이브러리를 통해 에디터를 등록하면 툴바의 경우 ".ql-toolbar", 텍스트 부분의 경우 ".ql-container"이라는 이름을 가진다. 이때 .ql-container 엘리먼트는 단순히 컨테이너의 기능만 수행하고, 진짜 에디터 기능은 ".ql-editor" 엘리먼트가 수행한다.

 위 정보를 종합하면, 우리가 글을 작성하는 영역인 ql-editor 영역을 감싸고 있는 ql-container의 높이에 제한을 줌으로써 스크롤 기능을 구현할 수 있게 된다. 커스텀 툴바를 구현한다든지 하는 노력은 필요하지 않다.

/* write section 용도. 스크롤 바로 동작! */
.ql-container.ql-snow {
  border-style: none !important; /* 기본적으로 있는 border 지정. */
  height: 400px;
}

.ql-editor {
  font-size: 16px; /* 기본 폰트 사이즈 지정 */
}

위와 같이 css 정보를 추가하고, 해당 css 파일을 Quill 컴포넌트가 사용되는 곳에서 import 하면 다음과 같다.

css 속성을 등록한 모습


참고로, Next.js 환경에서 React-Quill을 아무런 설정 없이 사용하면 다음과 같은 에러가 발생한다.

Next.js에서 발생하는 에러

위 에러는 Quill.js의 동작 방식에 의해 발생한다. 해당 라이브러리는 html 상에 존재하는 엘리먼트의 id 또는 class 값을 기반으로 - 즉 css selector 기반으로 에디터로 변환할 대상을 찾게 된다. 이때 css selector 및 document 속성은 서버 측인 Node.js 환경에 존재하지 않으므로 Next.js의 서버사이드 렌더링이 동작하지 않는다.

<div id="editor">
  <p>Hello World!</p>
  <p>Some initial <strong>bold</strong> text</p>
  <p><br></p>
</div>

<!-- Include the Quill library -->
<script src="https://cdn.quilljs.com/1.3.6/quill.js"></script>

<!-- Initialize Quill editor -->
<script>
  var quill = new Quill('#editor', {
    theme: 'snow'
  });
</script>

위 코드는 공식 문서 기준 Quill 사용법을 알려주고 있다. 비단 Quill 뿐만 아니라 웹 상에서 동작하는 많은 라이브러리들이 위와 같이 동작하므로, 자바스크립트에 의해 클라이언트 측에서 처리되어야 한다.

Next.js에서 클라이언트 사이드 렌더링을 수행하게 만들기 위해서는 next/dynamic 또는 react.lazy를 이용하여 나중에 가져오도록 만들면 된다. next.js 공식문서에 다르면 next/dynamic 자체가 react.lazy와 Suspence의 조합된 것이라고 하니, 편하게 dynamic을 이용하자.

// 클라이언트 측에서 렌더링되도록 처리(document 요구)
const ReactQuill = dynamic(() => import('react-quill'),
  {
    ssr: false,
    loading: () => <Spinner />
  }
);

// 렌더링 부분
  return (
    <div className="m-4">
      <div className="border-[1px] border-base-400">
        <ReactQuill
          theme="snow"
          value={value}
          onChange={onChange}
          modules={moduleOptions}
        />
      </div>
      <div>문자 개수: {wcount}</div>
    </div>
  );

dynamic 옵션으로 ssr: false을 지정하여 SSR을 비활성화했다. 추가적으로 loading 컴포넌트로 Spinner을 추가하여 대기시간 동안 스피너를 표시하도록 설정했다.

로딩이 동작하는 모습


인터넷 상의 예시 중에 툴바를 따로 구성하는 경우가 많았는데, 커스텀 툴바를 사용하는 경우 툴바와 에디터 영역이 따로 로딩되는 바람에 에디터 영역이 완전히 로딩되고 자바스크립트 코드가 실행되기 전까지 툴바의 html 상 텍스트가 그대로 노출되는 문제가 있었다. 다행히도 스크롤 적용 방식은 html만 분석해도 커스텀 툴바를 적용하지 않고 처리할 수 있었기 때문에 툴바 및 에디터 영역을 자연스럽게 표현할 수 있게 되었다.

'javascript > react' 카테고리의 다른 글

[React] 개발 환경 프록시 설정  (0) 2022.12.06
[React] 타입스크립트와 children 사용  (0) 2022.10.01
[React] react-router  (0) 2022.01.06
[React] custom hook  (0) 2021.12.29
[React] react-redux  (0) 2021.12.24