1import React, { useCallback, useMemo, useState } from 'react';
2import SimpleMDE from 'react-simplemde-editor';
3import 'easymde/dist/easymde.min.css';
4import { getDownloadURL, ref, uploadBytes } from 'firebase/storage';
5import { storage } from '../firebase/client';
6
7const MarkdownEditor = () => {
8 const [_, setValue] = useState<string>();
9
10 const uploadImage = async (file: File): Promise<string> => {
11 const imageRef = ref(storage, `images/markdown-editor/${Date.now()}`);
12 await uploadBytes(imageRef, file);
13 return getDownloadURL(imageRef);
14 };
15
16 const onChange = useCallback((value: string) => {
17 setValue(value);
18 }, []);
19
20 const options = useMemo(() => {
21 return {
22 toolbar: [
23 'bold',
24 'italic',
25 'heading',
26 '|',
27 'quote',
28 'unordered-list',
29 'ordered-list',
30 '|',
31 'link',
32 'image',
33 ],
34 status: false,
35 spellChecker: false,
36 imageUploadFunction(file, onSuccess) {
37 if (file.type.match('image')) {
38 uploadImage(file).then((url) => onSuccess(url));
39 }
40 },
41 } as EasyMDE.Options;
42 }, []);
43
44 return (
45 <div className="relative">
46 <SimpleMDE onChange={onChange} options={options} />
47 </div>
48 );
49};
50
51export default MarkdownEditor;
エディターのスタイルはオプションから調整することができないので css を使って強引に上書きします。その際 Tailwind CSS のスタイルを使って CSS のコストを最適化しています。
オプションを設定することでメニューバーや挙動を調整することができます。EasyMDEにはプレビュー機能も備わっていますがありますがプレビュースタイルの上書きが大変なので値を使って自前でマークダウンをレンダリングする方法をお勧めします。