티스토리 뷰
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
타입지정도 되어있는 라이브러리라, 바로 적용이 되었다.
무엇보다, 바로 적용이 잘 된 것을 확인할 수 있었다.
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
링크
TAG
- React quill
- 다이나믹 프로그래밍
- seb
- SEB43기
- SEB43
- 프론트엔드
- 코테
- 코드스테이츠
- 프로그래머스
- Python
- 개인 프로젝트
- til
- Redux
- 브루드포스
- 감정일기장
- SEB 43기
- 감정 일기장
- dictionary
- SEB 43
- 프리프로젝트
- dfs
- BFS
- 그리디 알고리즘
- 프로젝트
- 백준
- 스택오버플로우
- 기술면접
- 회고
- useContext
- 인적성
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함