-
[React-Quill] inline style 적용하기Studying/React 2023. 7. 22. 14:52
개요
react-quill 에디터에서 비디오를 임베드할 때 항상 동일한 크기로 출력하고 싶었습니다. 그런데 react-quill의 html content 크기를 멋대로 조정할 수 있는 방법을 찾지 못했습니다.
문제 상황
따라서 이미지 핸들러처럼 커스텀 비디오 핸들러를 만드는 시도를 했습니다.
ql-hidden 클래스가 사라지면 video url을 입력하는 tooltip이 나오는 방식을 활용하여 다음과 같은 핸들러를 작성했습니다.
const videoHandler = useCallback((editor: any) => { const tooltip = document.querySelector('.ql-tooltip'); if (tooltip) { tooltip.className += ' ql-editing' tooltip.setAttribute('data-mode', 'video'); tooltip.setAttribute('style', 'left:-138.5px;top:28.5px;'); tooltip.classList.remove('ql-hidden'); } const input = tooltip?.childNodes[1] as HTMLInputElement; const saveButton = tooltip?.childNodes[2] as HTMLLinkElement; saveButton.onclick = () => { console.log('saveButtonClick') const videoUrl = input.value; const range = editor.getSelection(); editor?.clipboard.dangerouslyPasteHTML( range, makeIframeElement(videoUrl), ); } }, []);
하지만 별도의 inline style이 적용된 요소는 react-quill의 content 요소로 인식이 안되는 문제가 발생했습니다.
원인은 다음과 같았습니다.
dangerouslyPasteHTML을 사용하려고 하면, Quill 에디터는 quill 자체 표현에 맞지 않는 요소(인라인 스타일 포함)를 제거합니다.
따라서 비디오 핸들러를 별도로 만든다 한들 제가 원하는 비디오 스타일인 width=100%도 적용할 수 없었습니다.
해결 방법
그래서 결국 useChangeHtmlContent 훅을 만들었습니다.
import dompurify from "dompurify"; const headings = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']; const media = ['iframe', 'img']; const inlineElements = ['span', 'u', 'a', 'strong', 's', 'em']; const blockElements = ['p', 'br']; const ALLOWED_TAGS = [...headings, ...media, ...inlineElements, ...blockElements]; export default function useChangeHtmlContent() { const sanitizer = dompurify.sanitize; const sanitize = (htmlContent: string) => { return sanitizer(htmlContent, { ALLOWED_TAGS: ALLOWED_TAGS, ADD_ATTR: ['allow', 'allowfullscreen', 'frameborder', 'scrolling', 'href'] }) }; const setElementInlineStyle = (htmlContent: string) => { let copiedHtmlContent = htmlContent; copiedHtmlContent = copiedHtmlContent.replace(/<img/g, '<img style="width:100%; height:auto;"'); copiedHtmlContent = copiedHtmlContent.replace(/<iframe/g, '<iframe style="width:100%;" height="696"'); return copiedHtmlContent; } return [sanitize, setElementInlineStyle] as const; };
해당 커스텀 훅은 dompurify의 sanitize 객체와 setElementInlineStyle 함수를 반환합니다.
setElementInlineStyle 함수는 <img>, <iframe> 태그일 경우 inline style 문자열을 추가하는 동작을 수행합니다. 따라서 portfolioDetail.tsx에서 <img>와 <iframe>을 불러올 때 제가 원하는 width: 100%; 인라인 스타일이 적용됩니다.
'Studying > React' 카테고리의 다른 글
Firebase로 React 프로젝트 구축하기 (0) 2023.08.16 로그인 정보를 리덕스로 관리하는 이유에 대하여 (0) 2023.08.02 뒤로가기/새로고침 시 '정말 나가시겠습니까?' 모달 만들기 (0) 2023.07.18 Custom Hook에 ref를 전달하기 (Feat. React-Quill) (0) 2023.07.14 [react-quill] 커스텀 이미지 핸들러 구현하기 (0) 2023.07.14