Closed8

WYSIWYG エディターを作ってみる

janusweljanuswel

次を使ってみたいというボトムアップな発想で「じゃあ Markdown 書いたら即レンダリングされる WYSIWYG エディターを作ってみよ」てなった

ここらへん以外は省力化ということで Next.js で scaffolding する

janusweljanuswel

Prettier はいれとく

npm install --save-dev --save-exact prettier

設定は全部デフォルトで

janusweljanuswel

さて、本題ひとつめの Monaco Editor をインストールしてエディターを表示する

調べてみたところ @monaco-editor/react が小さくて使いやすそう

https://www.npmtrends.com/@monaco-editor/react-vs-react-monaco-editor-vs-monaco-editor-react

@monaco-editor namespace 使ってるけど公式じゃないってところには注意かな

とりま、こうして

npm install --save-exact @monaco-editor/react

こう

/pages/index.tsx
import React from "react";
import Head from "next/head";
import Editor from "@monaco-editor/react";

import styles from "../styles/Home.module.css";

export default function Home() {
  return (
    <div>
      <Head>
        <title>WYSIWYG editor</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main className={styles.main}>
        <Editor
          height="100vh"
          defaultLanguage="markdown"
          defaultValue="# Write your own story"
        />
      </main>
    </div>
  );
}

CSS は次のようにした

/styles/Home.module.css
.main {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

エディターだ!!

editor

janusweljanuswel

書いたやつを取得してパースするぞ!!!

reamrk.js はプラグインで動作を拡張していく感じみたい

React への変換プラグインがあったので使っちゃう

インストールして

npm install --save-exact \
    remark \
    remark-parse \
    remark-react

こう

/pages/index.tsx
import React from "react";
import Head from "next/head";
import Editor from "@monaco-editor/react";
import remark from "remark";
import parse from "remark-parse";
import remark2react from "remark-react";

import styles from "../styles/Home.module.css";

const initial = "# Write your own story";

export default function Home() {
  const [text, setText] = React.useState(initial);

  function handleChange(text) {
    setText(text);
  }

  return (
    <div>
      <Head>
        <title>WYSIWYG editor</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main className={styles.main}>
        <Editor
          height="100vh"
          width="50%"
          defaultLanguage="markdown"
          defaultValue={initial}
          onChange={handleChange}
        />
        <div className={styles.preview}>
          {remark().use(parse).use(remark2react).processSync(text).result}
        </div>
      </main>
    </div>
  );
}

CSS はこう

/styles/Home.module.css
.main {
  flex: 1;
  display: flex;
  flex-direction: row;
  justify-content: center;
}

.preview {
  width: 50%;
  padding: 16px;
}

.preview a {
  text-decoration: underline;
}

やったぜ!!

このスクラップは2021/04/04にクローズされました