マークダウンエディター

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にはプレビュー機能も備わっていますがありますがプレビュースタイルの上書きが大変なので値を使って自前でマークダウンをレンダリングする方法をお勧めします。

使用ライブラリ

参考サイト