티스토리 뷰

React-quill 내부의 이미지 사이즈를 조절하려고 

quill-image-resize-module-ts을 install 후에 quill에 적용해주었다.

 

quill-image-resize-module 을 설치했을 때는 타입 지정이 되어있지않아서 import에 오류가 발생하였다.

따라서 2시간정도를 구글링하면서 quill-image-resize-module-ts 을 설치하여 import 문제를 해결 할 수 있었다.

 

import { ImageResize } from 'quill-image-resize-module-ts';
Quill.register('modules/ImageResize', ImageResize);


	....
  const modules = useMemo(() => {
    return {
      // syntax: {
      //   highlight: (text: any) => hljs.highlightAuto(text).value,
      // },
      toolbar: {
        syntax: true,
        container: [
          [{ header: [1, 2, false] }, { header: '2' }, { font: [String] }],
          [{ size: [String] }],
          ['bold', 'italic', 'underline', 'strike', 'blockquote'],
          [{ list: 'ordered' }, { list: 'bullet' }, { indent: '-1' }, { indent: '+1' }],
          ['link', 'image', 'code-block'],
          ['clean'],
        ],
        // handlers: {
        //   image: imageHandler,
        // },
      },
      // 이미지 조절 시 오류
      ImageResize: {
        modules: ['Resize', 'DisplaySize', 'Toolbar'],
      },
    };
  }, []);

  const formats = [
    'header',
    'font',
    'size',
    'bold',
    'italic',
    'underline',
    'strike',
    'blockquote',
    'list',
    'bullet',
    'indent',
    'link',
    'image',
    'video',
    'code-block',
  ];

  return (
    <S.DetailContainer>
      <S.Title>{text}</S.Title>
      <ReactQuill
        ref={quillRef}
        modules={modules}
        onChange={setContent}
        value={content}
        theme='snow'
      />
    </S.DetailContainer>
  );
};

 

문제 없이 작동되나 싶었는데, 이미지를 추가 후, 클릭하면 아래와 같은 오류가 발생하였다.

스타일을 불러올 수 없다는 오류같아서, 동일한 오류들을 찾아보고,

다른 버전의 라이브러리들을 설치하고 삭제하고 반복해도 해결되지 않았다.

하루를 매달리고 진행하였지만, 도저히 해결할 수 없어서 다른 라이브러리를 사용하였다.

 

https://github.com/xeger/quill-image

 

GitHub - xeger/quill-image

Contribute to xeger/quill-image development by creating an account on GitHub.

github.com

 

타입지정도 되어있는 라이브러리라, 바로 적용이 되었다.

무엇보다, 바로 적용이 잘 된 것을 확인할 수 있었다.

 

import React, { useEffect, useMemo, useRef, useState } from 'react';
import * as S from './DetailBox.style';
import hljs from 'highlight.js/lib/core';
import javascript from 'highlight.js/lib/languages/javascript';
import python from 'highlight.js/lib/languages/python';
import typescript from 'highlight.js/lib/languages/typescript';
import c from 'highlight.js/lib/languages/c';
import ReactQuill, { Quill } from 'react-quill';
import 'react-quill/dist/quill.snow.css';
import axios from 'axios';
import { ImageActions } from '@xeger/quill-image-actions';
import { ImageFormats } from '@xeger/quill-image-formats';

//Quill에 등록
Quill.register('modules/imageActions', ImageActions);
Quill.register('modules/imageFormats', ImageFormats);

type DetailBoxProps = {
  text: string;
  content: string;
  setContent: React.Dispatch<React.SetStateAction<string>>;
};

hljs.registerLanguage('javascript', javascript);
hljs.registerLanguage('python', python);
hljs.registerLanguage('typescript', typescript);
hljs.registerLanguage('c', c);

const DetailBox: React.FC<DetailBoxProps> = ({ text, content, setContent }) => {
  const quillRef = useRef<ReactQuill | null>(null);
  // 이미지 처리를 하는 핸들러
  const imageHandler = () => {
    console.log('에디터에서 이미지 버튼을 클릭하면 이 핸들러가 시작됩니다!');
    if (!quillRef.current) return;
    const quillInstance: any = quillRef.current.getEditor();
    // 1. 이미지를 저장할 input type=file DOM을 만든다.
    const input = document.createElement('input');
    // 속성 써주기
    input.setAttribute('type', 'file');
    input.setAttribute('accept', 'image/*');
    input.click(); // 에디터 이미지버튼을 클릭하면 이 input이 클릭된다.
    // input이 클릭되면 파일 선택창이 나타난다.

    input.onchange = async () => {
      const file = input.files![0];
      const formData = new FormData();
      formData.append('image', file);

      // 이미지를 서버로 전송 (서버 엔드포인트 주소를 사용)
      const response = await axios.post('YOUR_SERVER_API_URL', {
        body: formData,
      });

      const imageUrl = await response;
      const range = quillInstance.getSelection(true);
      quillInstance.insertEmbed(range.index, 'image', imageUrl);
    };
  };

  const formats = [
    'align',
    'background',
    'blockquote',
    'bold',
    'code-block',
    'color',
    'float',
    'font',
    'header',
    'height',
    'image',
    'italic',
    'link',
    'script',
    'strike',
    'size',
    'underline',
    'width',
    'image',
  ];

  const modules = useMemo(() => {
    return {
      imageActions: {},
      imageFormats: {},
      toolbar: {
        container: [
          ['bold', 'italic', 'underline', 'strike'], // toggled buttons
          ['blockquote', 'image', 'code-block'],

          [{ header: 1 }, { header: 2 }], // custom button values
          [{ list: 'ordered' }, { list: 'bullet' }],
          [{ script: 'sub' }, { script: 'super' }], // superscript/subscript
          [{ indent: '-1' }, { indent: '+1' }], // outdent/indent
          [{ direction: 'rtl' }], // text direction

          [{ size: ['small', false, 'large', 'huge'] }], // custom dropdown
          [{ header: [1, 2, 3, 4, 5, 6, false] }],

          [{ color: [] }, { background: [] }], // dropdown with defaults from theme
          [{ font: [] }],
          [{ align: [] }],

          ['clean'],
        ],

        // 내부 이미지를 url로 받아오는 handler
        handlers: {
          image: imageHandler,
        },
      },
    };
  }, []);

  return (
    <S.DetailContainer>
      <S.Title>{text}</S.Title>
      <ReactQuill
        ref={quillRef}
        formats={formats}
        modules={modules}
        onChange={setContent}
        value={content}
        theme='snow'
      />
    </S.DetailContainer>
  );
};

export default DetailBox;

 

 

우선 라이브러리를 설치 해준다.

 

npm install @xeger/quill-image-actions --save-prod
npm install @xeger/quill-image-formats --save-prod

그 후, import를 해주고 Quill에 등록시켜준다,

import { Quill } from 'react-quill';
import { ImageActions } from '@xeger/quill-image-actions';
import { ImageFormats } from '@xeger/quill-image-formats';

Quill.register('modules/imageActions', ImageActions);
Quill.register('modules/imageFormats', ImageFormats);

 

아래 형식으로 formats,modues를 설정해준 뒤, ReactQuill에 등록해준다.

(formats,modules는 아래의 예시에서 추가하여 사용가능 하다)

import React from 'react';
import ReactQuill from 'react-quill';

const formats = ['align', 'float'];
const modules = {
  imageActions: {},
  imageFormats: {},
  toolbar: [
    [{ 'align': [] }],
    ['clean']
  ]
};

export const Editor(): React.FC = () => (
  <ReactQuill
    formats={formats}
    modules={modules}
    theme="snow"
  />
);

 

'프로젝트 > 실물(silmul)' 카테고리의 다른 글

OAuth 로그인 구현  (0) 2023.05.24
react query  (0) 2023.05.15
Quill editor 내부의 사진 서버로 보내기  (0) 2023.05.14
login 전역상태관리  (0) 2023.05.12
Redux toolkit  (0) 2023.05.10
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함