TOAST UIのMarkdownエディタのReact版にTypeScriptの型が付いたよ
TOAST UIというWebのUIツールキットにMarkdownエディタがあるのですが、これがかなり便利で、以前記事を書いたQiitaクローンで使っています。
↓こんなエディタが簡単に作れます
ただ、このエディタのReact版はTypeScriptの型定義がなかったので自分で型を付けて使っていました...が今日最新版にアップデートしたら元々のリポジトリがdeprecated化&ソースがエディタ本体のリポジトリに移動&型定義が作成されていました。
こちらが元のリポジトリ
github.com
こちらが移動後のリポジトリ
github.com
npmのパッケージ自体は@toast-ui/react-editor
から変わっていないので単純にアップデートすればOKです。
以前はあまりメンテナンスされていない感じだったのですが、本体に取り込まれたのもあり、今のところ活発にメンテナンスされているようです。
今後どうなるかは怪しい部分もありますが、WebでMarkdownエディタを組み込むのであればオススメのライブラリです。
ちなみにVue.js版もあります。
github.com
供養
これを書くために記事をしたためたのですが、このエディタは普通に使おうと思うと
<div id="editor"></div>
const editor = new toastui.Editor({ el: document.querySelector('#editor'), previewStyle: 'vertical', height: '500px', initialValue: content });
こんな感じのコードになるのですが、QiitaクローンはReact製なのでこんなことはしたくないわけです。
自分でラップしてもいいんですが、前述の通り公式のReactコンポーネントが用意されているのでそれを使っていました&自分で型を付けていました。
せっかく作ったので、役に立つことはないと思いますがコードを置いておきます。
declare module "@toast-ui/react-editor";
// Editor.tsx import { Editor as TuiEditor, Viewer as TuiViewer } from "@toast-ui/react-editor"; import "codemirror/lib/codemirror.css"; import "highlight.js/styles/gml.css"; import React from "react"; import "tui-editor/dist/tui-editor-contents.min.css"; import "tui-editor/dist/tui-editor-extChart"; import "tui-editor/dist/tui-editor-extColorSyntax"; import "tui-editor/dist/tui-editor-extScrollSync"; import "tui-editor/dist/tui-editor-extTable"; import "tui-editor/dist/tui-editor-extUML"; import "tui-editor/dist/tui-editor.min.css"; interface Hooks { previewBeforeHook: (...args: any[]) => void; addImageBlobHook: ( fileOrBlob: File | Blob, callback: (...args: any[]) => void, source: string ) => void; } interface ToMarkOptions { gfm?: boolean; renderer?: any; } interface Converter { getMarkdownitHighlightRenderer(): markdownit; initHtmlSanitizer(): void; toHTML(makrdown: string): string; toHTMLWithCodeHightlight(markdown: string): string; toMarkdown(html: string, toMarkdownOptions: ToMarkOptions): string; } interface EditorProps { height?: string; minHeight?: string; initialValue?: string; previewStyle?: "tab" | "vertical"; initialEditType?: "markdown" | "wysiwyg"; onLoad?: (...args: any[]) => void; onChange?: (...args: any[]) => void; onStateChange?: (...args: any[]) => void; onFocus?: (...args: any[]) => void; onBlur?: (...args: any[]) => void; hooks?: Array<Hooks>; language?: string; useCommandShortcut?: boolean; useDefaultHTMLSanitizer?: boolean; codeBlockLanguages?: Array<string>; usageStatistics?: boolean; toolbarItems?: string; hideModeSwitch?: boolean; exts?: Array<any>; customConvertor?: Converter; placeholder?: string; previewDelayTime?: string; linkAttribute?: any; } interface ViewerProps { initialValue?: string; onLoad?: (...args: any[]) => void; onChange?: (...args: any[]) => void; onStateChange?: (...args: any[]) => void; onFocus?: (...args: any[]) => void; onBlur?: (...args: any[]) => void; hooks?: Array<Hooks>; exts?: Array<any>; } export const Editor = React.forwardRef<any, EditorProps>((props, ref) => ( <TuiEditor ref={ref} usageStatistics={false} exts={[ { name: "chart", minWidth: 100, maxWidth: 600, minHeight: 100, maxHeight: 300 }, "scrollSync", "colorSyntax", "uml", "mark", "table" ]} {...props} /> )); export const Viewer = React.forwardRef<any, ViewerProps>((props, ref) => ( <TuiViewer ref={ref} exts={[ { name: "chart", minWidth: 100, maxWidth: 600, minHeight: 100, maxHeight: 300 }, "scrollSync", "colorSyntax", "uml", "mark", "table" ]} {...props} /> ));
見ての通り、結局ラップしてるだけじゃねーか、という感じではあります...。