외부 버튼 활용하기
예제 바로 확인하기
다음 명령어로 프로젝트를 로컬 개발 환경에서 실행하면 예제를 바로 확인할 수 있습니다.
| URL | Description | Command |
|---|---|---|
https://localhost:3032 | 예제 데모 페이지 | yarn dev |
https://localhost:3033/react-video-thumbnail-extractor/ | 가이드 문서 | yarn docs |
sh
yarn devsh
npm devsh
pnpm devReact Quill 패키지 설치하기
다음 명령어를 사용해 React Quill 에디터 패키지를 설치하세요. 예제에서는 react-quill-new 패키지 3.3.3 버전 을 사용합니다. React Quill GitHub
가급적 React 18+를 지원하는 react-quill-new 패키지를 설치해 주세요.
sh
yarn add react-quill-new@3.3.3sh
npm install react-quill-new@3.3.3sh
pnpm add react-quill-new@3.3.3예제 코드 소스
React Quill 패키지의 테마 스타일 파일과 컴포넌트 파일을 함께 import하는 것, 잊지 마세요!
- onSuccess 콜백 함수에서 받은 썸네일 목록에서
Base64 URL만 추출한 후에 에디터에 추가합니다.
tsx
// ...중략
const handleSuccess = (thumbnails: Thumbnail[]) => {
// 썸네일 목록 배열에서 React Quill 에디터가 지원하는 Base64 URL만 추출
const thumbnailUrls = thumbnails.map((thumbnail) => thumbnail.base64Url);
handleInsertThumbnails(thumbnailUrls);
closeModal();
};- Base64 URL만 있는 배열로
<img>태그를 만든 후, 에디터 Value를 설정합니다.
tsx
const handleInsertThumbnails = (thumbnailUrls: string[]) => {
if (thumbnailUrls.length < 1) return;
const imageTags = thumbnailUrls.map((url) => `<p><img src="${url}" /></p><p></p>`).join('');
setEditorContent((prevContent) => prevContent + imageTags);
};/react-quill/DemoBasic.tsx
tsx
import 'react-quill-new/dist/quill.snow.css';
import './style.css';
import '@devskyui/react-video-thumbnail-extractor/style.css';
import type {
Thumbnail,
ThumbnailValidationResult,
VideoThumbnailExtractorMessagesType
} from '@devskyui/react-video-thumbnail-extractor';
import {
VideoThumbnailExtractorMessages,
VideoThumbnailExtractorModal
} from '@devskyui/react-video-thumbnail-extractor';
import { useState } from 'react';
import toast from 'react-hot-toast';
import { AiOutlineVideoCameraAdd } from 'react-icons/ai';
import ReactQuill from 'react-quill-new';
const messages: VideoThumbnailExtractorMessagesType['ko'] = VideoThumbnailExtractorMessages.ko;
export const DemoBasic = () => {
const [editorContent, setEditorContent] = useState('');
const [isOpen, setIsOpen] = useState(false);
const openModal = () => {
setIsOpen(true);
};
const closeModal = () => {
setIsOpen(false);
};
const handleAddedThumbnail = (thumbnail: Thumbnail) => {
const time = thumbnail.displayTime;
toast.success(`${time} ${messages.THUMBNAIL_ADD_SUCCESS}`);
};
const handleRemovedThumbnail = (thumbnail: Thumbnail) => {
const time = thumbnail.displayTime;
toast.success(`${time} ${messages.THUMBNAIL_REMOVE_SUCCESS}`);
};
const handleSuccess = (thumbnails: Thumbnail[]) => {
const thumbnailUrls = thumbnails.map((thumbnail) => thumbnail.base64Url);
handleInsertThumbnails(thumbnailUrls);
closeModal();
};
const handleError = (result: ThumbnailValidationResult) => {
const message = messages?.[result?.code];
if (message) {
toast.error(message);
}
};
const handleInsertThumbnails = (thumbnailUrls: string[]) => {
if (thumbnailUrls.length < 1) return;
const imageTags = thumbnailUrls.map((url) => `<p><img src="${url}" /></p><p></p>`).join('');
setEditorContent((prevContent) => prevContent + imageTags);
};
return (
<>
<ReactQuill
value={editorContent}
onChange={setEditorContent}
placeholder="에디터 밖 버튼을 눌러 이미지를 삽입해 보세요."
/>
<button
onClick={() => openModal()}
className="mt-2.5 flex items-center justify-center gap-1 rounded-full bg-primary px-4 py-2 text-primaryDark transition-colors duration-300 hover:bg-primaryDark hover:text-white"
>
<AiOutlineVideoCameraAdd />
<span className="text-xs font-bold">동영상에서 썸네일 가져오기</span>
</button>
<VideoThumbnailExtractorModal
isOpen={isOpen}
maxFileSize={300}
maxThumbnailLength={4}
onThumbnailAdded={handleAddedThumbnail}
onThumbnailRemoved={handleRemovedThumbnail}
onError={handleError}
onSuccess={handleSuccess}
onCancel={() => closeModal()}
/>
</>
);
};