tag:crieit.net,2005:https://crieit.net/tags/TOASTUIEditor/feed 「TOASTUIEditor」の記事 - Crieit Crieitでタグ「TOASTUIEditor」に投稿された最近の記事 2020-06-07T23:44:07+09:00 https://crieit.net/tags/TOASTUIEditor/feed tag:crieit.net,2005:PublicArticle/15925 2020-06-07T23:44:07+09:00 2020-06-07T23:44:07+09:00 https://crieit.net/posts/NextJS-5edcfd37d54af NextJSでマークダウンエディタを扱う際の注意点 <h2 id="SSR(サーバサイドレンダリング)の影響"><a href="#SSR%28%E3%82%B5%E3%83%BC%E3%83%90%E3%82%B5%E3%82%A4%E3%83%89%E3%83%AC%E3%83%B3%E3%83%80%E3%83%AA%E3%83%B3%E3%82%B0%29%E3%81%AE%E5%BD%B1%E9%9F%BF">SSR(サーバサイドレンダリング)の影響</a></h2> <p>draft.jsやtui-editorに共通して言えることですが、<br /> 元々ブラウザでの動作を想定して作られているので、<br /> NextJSなどのSSR環境下では<code>window</code>、<code>document</code>などの変数の中身が<code>undefined</code>になり、動作しなくなります。</p> <h2 id="Next.JSではSSRを無効にできる"><a href="#Next.JS%E3%81%A7%E3%81%AFSSR%E3%82%92%E7%84%A1%E5%8A%B9%E3%81%AB%E3%81%A7%E3%81%8D%E3%82%8B">Next.JSではSSRを無効にできる</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://nextjs.org/docs/advanced-features/dynamic-import#with-no-ssr">With no SSR</a></p> <p>インポート方法を変えることでSSRを無効にできるオプションがあります。<br /> dynamic import自体はES2020で導入される構文だとか。</p> <pre><code class="typescript">const DraftEditorNoSSR = dynamic<DraftEditorProp>( () => import('../components/DraftEditor') as any, { ssr: false } ) </code></pre> <h2 id="Draft.jsを断念した理由"><a href="#Draft.js%E3%82%92%E6%96%AD%E5%BF%B5%E3%81%97%E3%81%9F%E7%90%86%E7%94%B1">Draft.jsを断念した理由</a></h2> <p>draft.jsでは再描画した際にカーソルが行の先頭に戻るというバグがあります。<br /> 公式リポジトリでは行の最後に移動する対処も議論されていますが、文章の中で編集したくなったらどうするんだ....という声もちらほら。</p> <p><a target="_blank" rel="nofollow noopener" href="https://github.com/facebook/draft-js/issues/1198">How to stop DraftJS cursor jumping to beginning of text?</a></p> <p>さっさと見切りをつけてToastUI editorに移りました。<br /> そうです、crieitにも採用されているエディタですね。</p> <h2 id="Toast UI Editorで実装できた!"><a href="#Toast+UI+Editor%E3%81%A7%E5%AE%9F%E8%A3%85%E3%81%A7%E3%81%8D%E3%81%9F%21">Toast UI Editorで実装できた!</a></h2> <p>ただし、Toast UI Editorはrefを使わないと値が取れず、<br /> マウントされていない状態でrefがnullになってしまうことにかなり苦しめられました。</p> <p>changeイベントがeditorで発火するのでフラグを更新するようにして、外側でrefを使ってデータを取り出すという実装になりました。<br /> それから、画像アップロードをdisabledにしました。</p> <p>editorコンポーネントを使いまわしたかったので、<br /> 表示用の初期値<code>initialValue</code>と値を更新して外部に渡す<code>setFunc</code>をpropsとして与えています。</p> <pre><code class="javascript">const DraftEditor = ({ initialValue, setFunc }) => { const editorRef = createRef<Editor>(); const [changed, setChanged] = useState(false); useEffect(() => { if (editorRef.current && changed) { setFunc(editorRef.current.getInstance().getMarkdown()); console.log("set"); setChanged(false); } }, [editorRef.current, changed]); return ( <div style=<span>{</span><span>{</span> width: "100vw", <span>}</span><span>}</span> > <div> <Editor previewStyle="vertical" toolbarItems={[ "heading", "bold", "italic", "strike", "divider", "hr", "quote", "ul", "ol", "task", "table", "link", "divider", ]} height="400px" initialEditType="markdown" initialValue={initialValue} ref={editorRef} hideModeSwitch={true} events=<span>{</span><span>{</span> change: (e) => { setChanged(true); }, <span>}</span><span>}</span> /> </div> </div> ); }; export default DraftEditor; export type DraftEditorProp = { initialValue: string; setFunc: Dispatch<any>; }; </code></pre> ckoshien tag:crieit.net,2005:PublicArticle/15777 2020-03-25T08:31:01+09:00 2020-03-25T08:35:46+09:00 https://crieit.net/posts/TOAST-UI-Editor2 TOAST UI Editor2のツールバーに独自のボタンアイコンを追加する <p>このサービスでも使っているTOAST UI Editorはいつの間にかバージョン2が出ていたようです。npmのパッケージも別になったので入れ直しが必要です。プラグインなども別パッケージになったので、軽くなっていると思います(元々すごく容量が大きいので……アップグレード推奨だと思います)</p> <p>また、微妙にカスタマイズ方法も変わっており、以前投稿した <a href="https://crieit.net/posts/TOAST-UI-Editor">TOAST UI Editorのツールバーに独自のボタンアイコンを追加する</a> ではエラーになるようです。うまく行った方法をメモしておきます。</p> <p>ちなみに公式の説明は下記です。</p> <p><a target="_blank" rel="nofollow noopener" href="https://nhn.github.io/tui.editor/latest/tutorial-example19-customizing-toolbar-buttons">19. Customizing Toolbar Buttons</a></p> <h2 id="ツールバーにボタンなどを追加する"><a href="#%E3%83%84%E3%83%BC%E3%83%AB%E3%83%90%E3%83%BC%E3%81%AB%E3%83%9C%E3%82%BF%E3%83%B3%E3%81%AA%E3%81%A9%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%99%E3%82%8B">ツールバーにボタンなどを追加する</a></h2> <p>以前書いたような、addDividerやaddButtonはなくなりました。基本的に <code>addItem</code> に <code>type</code> を指定して使うことになります。</p> <pre><code class="javascript"> const toolbar = editor.getUI().getToolbar() editor.eventManager.addEventType('event1') editor.eventManager.listen('event1', () => { alert('button click!'); }) toolbar.addItem({ type: 'divider' }) const button = document.createElement('button') button.className = 'tui-toolbar-icons custom' button.innerHTML = `<i class="material-icons">help_outline</i>` toolbar.addItem({ type: 'button', options: { name: 'buttonname', event: 'event1', tooltip: 'ツールチップ', el: button } }) </code></pre> <p>バージョン1との違いとして、jQueryは削除されたので指定する <code>el</code> はcreateElementで作成した生のものになります。また、elのドルマークも不要です。</p> <p>ちなみに型定義が入っているのでTypeScriptで使いやすくはなっているのですが、こういうカスタマイズをすると型定義が足りずにビルドができなくなります。そのためanyにするなり独自の型定義を入れなければなりません。ここはまだ微妙ですがまだ2がリリースされたばかりなので今後改善されていくでしょう。</p> <p>CSSをいじらないとボタンがうまく表示されなかったかもしれませんので、それは前述した以前の投稿を確認してみてください。</p> だら@Crieit開発者 tag:crieit.net,2005:PublicArticle/14655 2018-12-13T23:38:58+09:00 2020-03-25T08:33:16+09:00 https://crieit.net/posts/TOAST-UI-Editor TOAST UI Editorのツールバーに独自のボタンアイコンを追加する <p>TOAST UI Editorには元々ツールバーがついていますが、そちらはカスタマイズが可能です。</p> <p>(追記:バージョン2用の記事も書きました <a href="https://crieit.net/posts/TOAST-UI-Editor2">TOAST UI Editor2のツールバーに独自のボタンアイコンを追加する</a>)</p> <p>具体的にはリポジトリのサンプルプログラムに方法が書かれています。</p> <p><a target="_blank" rel="nofollow noopener" href="https://github.com/nhnent/tui.editor/blob/master/examples/example16-toolbar-add-button-fontawesome.html">example16-toolbar-add-button-fontawesome.html</a></p> <p>1つ目の方法として、エディタを初期化する際に下記のようなパラメータを指定する事ができます。</p> <pre><code class="javascript"> toolbarItems: [ 'heading', 'bold', 'italic', 'strike', 'divider', 'hr', 'quote', 'divider', 'ul', 'ol', 'task', 'indent', 'outdent', 'divider', 'table', 'image', 'link', 'divider', 'code', 'codeblock', 'divider', { type: 'button', options: { $el: $('<div class="our-button-class"><i class="fas fa-briefcase-medical"></i></div>'), name: 'test2', className: '', command: 'Bold', tooltip: 'Bold' } } ] </code></pre> <p>ただこの方法だと全て指定しなければなりません。一つだけ追加したい場合などもサンプルに書かれています。僕が実際に対応した際は下記のようにしました。Material Iconsを使った場合の例です。Dividerの例も追加してあります。</p> <pre><code class="javascript"> const toolbar = editor.getUI().getToolbar() editor.eventManager.addEventType('Event1'); editor.eventManager.listen('Event1', () => { alert('button click!'); }); toolbar.addDivider() toolbar.addButton({ name: 'customize', event: 'Event1', tooltip: 'Apple!!!', $el: $( '<button class="tui-toolbar-icons custom"><i class="material-icons">help_outline</i></button>' ) }); </code></pre> <p>一応classNameやtextのパラメータも指定できるのですが、結構調整が大変です。余裕があれば試してみてください。</p> <p>今回の場合正しく表示させるためにはCSSも定義してあげる必要があります。(不具合か何かはわかりませんが、こうしないとおかしな表示になってしまいます)</p> <pre><code class="scss">.custom.tui-toolbar-icons { background-image: none; padding: 0; i.material-icons { color: #000; font-size: 21px; } } </code></pre> <p>ちょっとこのあたりまだライブラリ自体に手探り感が残っていますね。</p> だら@Crieit開発者