コードエディター実装してみた
投稿日: 2024年12月06日
学習サイトの実装が楽しみ過ぎて、そして暇すぎて、打ち合わせもまだだというのにコードエディターを実装してみました。
このライブラリで良いのかも確認してないのに。(なんでもいいって言われると思う)
結構わかりにくくて気づいたら眠くなったのでちゃちゃっとまとめます。
ホントにコードエディター作っただけなのでそのまま貼ります♡
コードエディターのライブラリは色々ありましたが、私調べでreact-ace
が使いやすそうでちょっと一旦これでやってみようと思いました。
名前にreactってついているだけでなんか安心感もあります。
Next.js:15.0.3
react-ace:13.0.0
npm install react-ace
"use client";
import { useState } from "react";
import AceEditor from "react-ace";
import "ace-builds/src-noconflict/mode-javascript";
import "ace-builds/src-noconflict/theme-Monokai";
export const Editor: React.FC = () => {
const [editValue, setEditValue] = useState("");
return (
<div className="p-5 flex flex-col items-center gap-5">
<AceEditor
placeholder="回答を入力してください"
mode="javascript"
theme="monokai"
fontSize={14}
lineHeight={19}
onChange={value => setEditValue(value)}
showPrintMargin={true}
showGutter={true}
highlightActiveLine={true}
value={editValue}
setOptions={{ useWorker: false }}
className="!h-[800px] !w-2/3 "
/>
<button
type="button"
onClick={() => console.log(editValue)}
className="bg-black text-white px-2 py-1 rounded-md"
>
consoleに表示
</button>
</div>
);
};
import AceEditor from "react-ace";
import "ace-builds/src-noconflict/mode-javascript";
import "ace-builds/src-noconflict/theme-Monokai";
AceEditorに渡すPropsによりインポートするものが変わるのですが、私は下記の二つをインポートしています。
mode:言語
theme:エディターのテーマ(見た目)
modeが一旦はJSですが、実際は多分複数インポートして変更することになるかなとは思ってます。
最初何渡すんかなと思ってライブラリの型をみたところ、両方stringだったんです。
これがenum型でそのままそれっぽいの選んで渡せば終わりであれと思ったけど違うから仕方ないです。
便利なものを作ってくれてありがとうの気持ちで探しました。
モード「\node_modules\ace-builds\src-noconflict\ext-modelist.js」
テーマ「\node_modules\ace-builds\src-noconflict\ext-themelist.js」
それぞれ上記のファイルを確認してそこから選びました。
デモサイトがあるので、テーマはそこから選んで、ファイルの中の一覧から確認したらちゃんと選べて早そうです。
https://securingsincity.github.io/react-ace/
埋め込み取得出来ずでそのままただのリンク貼ります_(._.)_
const [editValue, setEditValue] = useState("");
いつも通りですが、コードの中身はあとで使うのでステートで管理します。
<AceEditor
placeholder="回答を入力してください"
mode="javascript"
theme="monokai"
fontSize={14}
lineHeight={19}
value={editValue}
onChange={value => setEditValue(value)}
showPrintMargin={true}
showGutter={true}
highlightActiveLine={true}
setOptions={{ useWorker: false }}
className="!h-[800px] !w-2/3 "
/>
一部少し詳しく見ていきます。
インポートしたmodeとthemeは小文字オンリーで書きます。
ファイル名に惑わされてはいけません。
mode="javascript"
theme="monokai"
ステートの値を表示して、変更の度にステートを更新します。
value={editValue}
onChange={value => setEditValue(value)}
こちら書かないと謎エラー吐きます。
setOptions={{ useWorker: false }}
Uncaught NetworkError: Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at '
' failed to load.
ネットワークタブ404エラー吐いてて、なんやこれと思って結構時間かかりました🥺
スタイルはimportantにしないと効かないです。
style属性にデフォルトで直接"width: 500px; height: 500px;があたっていました。
適当に大きさ変えてみました。
className="!h-[800px] !w-2/3 "
終わってみたら簡単そうって思うんですけど、謎エラー消そうと思ったら結構ハマりました。
これが使えるのかはわかりませんが、とりあえずブログのネタになったからやって悪かったってことはないやろと思って書きました。
まだまだこれから考えることが多いので、ライブラリの使い方で時間溶かさないように頑張らないと・・💪