This translation is older than the English page and may be missing recent changes.
Read the English versionテキストエリアを置き換えるのではなく拡張するマークダウン エディターにより、フォームの送信、検証、および必須フィールドが機能し続けます。 WYSIWYG およびプレーン Markdown モード、ライブ プレビュー、検索と置換、RTL サポート、ダーク モード。 Django、Laravel、Rails、Node.js、PHP、およびあらゆるスタックでスタンドアロンで動作します。
Frutjam も Tailwind も必要ありません。 スタイルがバンドルされているため、エディターはどのプロジェクトにもドロップできます。
インストール
NPM (バンドラー: Vite、webpack、Rollup など)
npm install markdown-text-editor |
1 2 | import MarkdownEditor from 'markdown-text-editor'; new MarkdownEditor('#markdown-editor'); |
TypeScript 定義はパッケージに同梱されているため、オプション、ツールバーのエントリ、変数の形状がチェックされ、追加のインストールなしでオートコンプリートされます。
型もインポート可能です。これは、オプションが呼び出しサイトでインラインで記述されていない場合に重要です。 TypeScript は、直接渡されたオブジェクト リテラルの不明なキーのみをチェックするため、独自の変数に保持されている設定では、スペルが間違っているキーは黙って無視されます。注釈を付けるとチェックが元に戻ります。
1 2 3 4 5 6 7 8 9 10 11 12 13 | import MarkdownEditor, { type MarkdownEditorOptions, type ToolbarEntry } from 'markdown-text-editor'; // Without the annotation this compiles, the editor renders with the default // toolbar, and nothing tells you why. const config: MarkdownEditorOptions = { placeholder: 'Write...', toolbr: ['bold', 'preview'], // Error: did you mean to write 'toolbar'? }; // Building a toolbar conditionally const toolbar: ToolbarEntry[] = ['bold', 'italic']; if (canUpload) toolbar.push({ image: { fileInput: { uploadUrl: '/api/upload' } } }); toolbar.push('preview'); |
同じことがラッパーコンポーネントにも当てはまります。 MarkdownEditorOptions の代わりに転送するものです anyしたがって、ラッパーを使用する人は誰でもチェックを続けます。
1 2 3 4 | interface EditorProps { value: string; options?: MarkdownEditorOptions; } |
CDN:ESモジュール
1 2 3 4 | <script type="module"> import MarkdownEditor from 'https://cdn.jsdelivr.net/npm/markdown-text-editor/+esm'; new MarkdownEditor('#markdown-editor'); </script> |
CDN: グローバル スクリプト タグ (IIFE)
インポートは必要ありません。MarkdownEditor はグローバル変数として自動的に使用可能です。
1 2 3 4 5 6 7 8 9 | <form action="/api/save" method="POST"> <textarea id="markdown-editor" name="content"># Hello World</textarea> <button type="submit">Save Content</button> </form> <script src="https://cdn.jsdelivr.net/npm/markdown-text-editor"></script> <script> new MarkdownEditor('#markdown-editor'); </script> |
マークダウン エディターのデモ
クイックスタート
エディターをカスタマイズするには、オプション オブジェクトを渡します。すべてのオプションはオプションです。デフォルト値を使用するには、いずれかを省略します。
1 2 3 4 | const editor = new MarkdownEditor('#markdown-editor', { placeholder: 'Write your markdown...', toolbar: ['heading', 'bold', 'italic', 'strikethrough', 'ul', 'ol', 'checklist', 'blockquote', 'link', 'preview'], }); |
理念:「ネイティブファースト」
ほとんどのエディターは標準的な Web ワークフローを壊します。 MarkdownEditor はこれを採用しています。直接上に置いてあるので、 <textarea>、データを処理する新しい方法を学ぶ必要はありません。
- データ バインディングは必要ありません: で動作します
<form method="POST">箱から出して - 標準アクセス: 使用
document.getElementById('editor').value通常の入力と同じように。 - バックエンドに依存しない: 通常のフォーム フィールドと同様に、あらゆるバックエンド (Python、Node.js、PHP など) で動作します。
MarkdownEditor と EasyMDE / SimpleMDE の比較
ほとんどの JavaScript マークダウン エディター (EasyMDE、SimpleMDE、CodeMirror ベースのエディター) ** <textarea>** コピーを編集し、フォームの送信時に内容を書き戻します。これは、他の何かがその値を必要とするまで機能します。 required ブラウザがフォーカスできないフィールドは送信を完全にブロックし、 .value または FormData 送信前に読み取ると空の文字列が返され、htmx、Turbo、自動保存、および未保存変更のガードが破られます。 MarkdownEditor は異なります。 既存のテキストエリアのスタイルを設定し、入力したフィールドのままにするため、値はいつでも正しい値になります。
| 特徴 | マークダウンエディタ | EasyMDE / SimpleMDE |
|---|---|---|
| ネイティブのテキストエリアが保持される | ✅ | ❌ 非表示、コピーとして編集 |
で動作します required フィールド | ✅ | ❌ ブラウザが送信をブロックする |
.value 送信する前に修正してください | ✅ | ❌ フォームが送信されるまで空のままにしてください |
と連載中 FormData、htmx、ターボ | ✅ | ❌ エディター独自の API が必要 |
| WYSIWYGハイブリッドモード | ✅ | ❌ |
| 組み込みの検索と置換 | ✅ | ❌ |
| RTLのサポート | ✅ 内蔵 | CodeMirror 経由 direction オプション |
| インライン イベント ハンドラー (CSP) | ✅ なし | いくつかの |
| ダークモード/テーマ設定 | ✅ | 限定 |
| バンドルのサイズ、gzip 圧縮 | 53KB | 107KB(JS+CSS) |
フレームワークの統合
MarkdownEditor はネイティブを保持するため、 <textarea>、追加のコードなしですべてのバックエンド フレームワークと統合されます。サーバーは、標準のフォーム フィールドから受け取る場合とまったく同じように、マークダウン コンテンツを受け取ります。 React と Vue の場合は数行かかりますが、これについてはこのセクションの最後で説明します。
ジャンゴ
追加 class テキストエリア ウィジェットに追加し、エディタを初期化します。 request.POST['content'] 追加の手順なしで動作します。
1 2 3 4 5 6 7 8 | # forms.py class PostForm(forms.ModelForm): class Meta: model = Post fields = ['content'] widgets = { 'content': forms.Textarea(attrs={'class': 'markdown-editor'}), } |
1 2 | new MarkdownEditor('.markdown-editor'); // request.POST['content'] contains the markdown on submit |
ララベル
使用 f.text_area クラスの場合: $request->input('content') マークダウンを直接受け取ります。
1 2 | <textarea name="content" class="markdown-editor">{{ old('content') }}</textarea> <script>new MarkdownEditor('.markdown-editor');</script> |
ルビー・オン・レール
で動作します form_with 箱から出して: params[:content] マークダウンが含まれています。ターボドライブの場合は、次を使用します。 turbo:load の代わりに DOMContentLoaded.
1 2 3 4 5 6 | document.addEventListener('turbo:load', () => { document.querySelectorAll('.markdown-editor:not([data-mde-init])').forEach(el => { el.setAttribute('data-mde-init', 'true'); new MarkdownEditor(el); }); }); |
Node.js / Express
req.body.content フォーム送信時にマークダウンを受け取ります。同期ステップやカスタム抽出はありません。
1 2 3 | <textarea name="content" class="markdown-editor"></textarea> <script src="https://cdn.jsdelivr.net/npm/markdown-text-editor"></script> <script>new MarkdownEditor('.markdown-editor');</script> |
PHP
$_POST['content'] 標準のテキストエリアとまったく同じように機能します。ドロップインすると、既存のフォーム処理を変更する必要はありません。
1 2 3 4 5 6 | <form method="POST" action="save.php"> <textarea name="content" class="markdown-editor"></textarea> <button type="submit">Save</button> </form> <script src="https://cdn.jsdelivr.net/npm/markdown-text-editor"></script> <script>new MarkdownEditor('.markdown-editor');</script> |
反応する
エフェクト内にエディタを作成し、アンマウント時に破棄します。使用 defaultValue それよりも value: エディターはテキストエリアに直接書き込むため、制御されたバインディングはユーザーが入力している内容を上書きします。
1 2 3 4 5 6 7 8 9 10 11 12 13 | import { useEffect, useRef } from 'react'; import MarkdownEditor from 'markdown-text-editor'; function MarkdownField({ name, defaultValue = '', onChange }) { const ref = useRef(null); useEffect(() => { const editor = new MarkdownEditor(ref.current, { onChange }); return () => editor.destroy(); }, []); return <textarea ref={ref} name={name} defaultValue={defaultValue} />; } |
戻る editor.destroy() エフェクトからは、開発中にエフェクトを 2 回実行する StrictMode もカバーされており、そうでない場合は 1 つのテキストエリアに 2 つのエディターが残ることになります。空の依存関係配列は意図的です。オプションはエディターの作成時に一度読み取られるため、エフェクトを再実行するとエフェクトが破棄され、変更のたびに再構築されます。
ヴュー
同じ考えです。初期値を一度設定します onMounted そして束縛しないでください :value、または発行されたすべてのキーストロークが v-model テキストエリアを上書きします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <script setup> import { ref, onMounted, onBeforeUnmount } from 'vue'; import MarkdownEditor from 'markdown-text-editor'; const el = ref(null); const props = defineProps({ modelValue: { type: String, default: '' } }); const emit = defineEmits(['update:modelValue']); let editor = null; onMounted(() => { el.value.value = props.modelValue; editor = new MarkdownEditor(el.value, { onChange: value => emit('update:modelValue', value) }); }); onBeforeUnmount(() => editor?.destroy()); </script> <template><textarea ref="el"></textarea></template> |
として使用されます <MarkdownField v-model="content" />。単純な形式ではスキップできます v-model 他のフレームワークと同様に、送信時にテキストエリアから値を完全に読み取ります。
構成
エディターの動作とインターフェースを完全にカスタマイズするには、 options 物体。オプションを省略した場合は、デフォルト 値が使用されます。
オプションは、エディターの構築時に 1 回読み取られます。後で変更しても効果はありません。 destroy() 代わりに新しいエディタを作成します。
| 財産 | タイプ | デフォルト | 目的 |
|---|---|---|---|
mode | string | 'plain' | 初期ビューを設定します。 WYSIWYG エクスペリエンスにはハイブリッドを使用し、生の構文にはプレーンを使用します。 |
placeholder | string | 'Write...' | エディターが空の場合に表示されるテキスト。 |
toolbar | array | [...] | どのツールがどのような順序で表示されるかを定義します。 |
footer | 偽| オブジェクト | すべて見える | エディタの下に表示されるステータス バーを制御します。に設定します false 完全に非表示にするか、オブジェクトを渡して個々の統計を切り替えます。 |
theme | string | inherited | エディターのテーマ (ライト、ダーク、スノーベリー、ダークベリー) を明示的に設定します。省略した場合、エディタは継承します。 data-theme 最も近い祖先要素から、または <textarea> 自体。 |
minHeight | number | 200 | コンテンツが短い場合にエディターが縮小する最小の高さ (ピクセル単位)。とペアになります maxHeight 自動拡張範囲を設定します。 |
maxHeight | number | 500 | 非全画面モードでエディターが拡大できるピクセル単位の最大高さ。コンテンツがこの高さを超えると、エディター内にスクロールバーが表示されます。エディターにはドラッグ ハンドルもあるので、ユーザーはこの制限を超えて手動でサイズを変更できます。 |
renderer | function | marked | プレビューに使用されるマークダウン パーサーを置き換えます。マークダウン文字列を受け取り、HTML 文字列を返す必要があります。 |
sanitizer | function | DOMPurify | HTML サニタイザーを置き換えます。レンダリングされた HTML を受け取り、表示するには安全な HTML を返す必要があります。 |
onChange | function | undefined | コンテンツの変更 (入力、ツールバーのアクション、元に戻す/やり直し、リストの継続) ごとにコールバックが発生します。現在のマークダウン文字列を唯一の引数として受け取ります。 |
labels | object | undefined | エディター独自のインターフェイスの翻訳。英語の文字列をキーとします。省略したものはすべて英語のままです。 |
🛠 ツールバーのカスタマイズ
ツールバーはモジュール式です。アレイを変更することで、最小限のエクスペリエンスまたはフル機能のパワー スイートを作成できます。
利用可能なツール
| カテゴリ | ツールキー |
|---|---|
| タイポグラフィ | heading, bold, italic, strikethrough, blockquote |
| リスト | ul (bullet), ol (numbered), checklist |
| コード | code (列をなして)、 codeblock (柵で囲まれたブロック) |
| インサート | hr (横罫)、 table (テーブルテンプレート) |
| メディア | link, image |
| 編集 | undo, redo, indent, outdent |
| ビュー | preview |
| テンプレート | { variables: [...] }、インラインで構成 |
ツールリファレンス
| 道具 | 説明 |
|---|---|
heading | ドロップダウンを開いて見出しレベル H1 ~ H6 を選択します |
bold | 太字のテキストの書式設定を有効にします。 |
italic | 斜体のテキストの書式設定を有効にします。 |
strikethrough | テキストの取り消し線を許可します。 |
ol | (順序付きリスト): テキストを番号付きリスト形式に変換します。 |
ul | (順序なしリスト): テキストを箇条書きリストに変換します。 |
checklist | テキストにチェックボックスを追加して、タスク、To-Do リスト、または完了ステータスの追跡に最適にします。 |
blockquote | 引用または強調されたテキストを強調表示します。 |
code | インライン コードの場合、選択したテキストを単一のバッククォートで囲みます。もう一度クリックするとバッククォートが削除されます。 |
codeblock | 選択したテキストを 3 つのバッククォートで囲まれたコード ブロックで囲みます。もう一度クリックするとフェンスが削除されます。 |
hr | を挿入します --- 独自の行のカーソル位置に水平罫線を配置します。 |
table | スターター 2x3 マークダウン テーブル テンプレートをカーソル位置に挿入します。 |
image | マークダウン構文を使用して画像を挿入できます。 |
link | テキストにハイパーリンクを追加できます。 |
undo | 最後の変更を元に戻すには。 |
redo | 最後に元に戻した変更を再適用します。 |
indent | インデントレベルを上げるには。 |
outdent | インデントレベルを下げるには。 |
preview | 全画面の並べてプレビューを切り替えます。プレビュー ペインのチェックボックスはクリック可能で、マークダウン ソースが即座に更新されます。全画面表示を終了するには、Esc キーを押します。全画面表示で固定ヘッダーがエディターを覆う場合は、次を参照してください。 --mte-fullscreen-z-index. |
💡 実装のヒント:
- 並べ替え: ボタンは、配列にリストしたとおりの順序で表示されます。
- 削除: 任意のキーを単純に省略します (例:
image) 配列からその機能をユーザーに対して完全に無効にします - ネイティブ フォールバック:
placeholderJS では、プラグインは自動的にplaceholderHTML の属性<textarea>
🧩 カスタムツール
フォークせずに独自のツールバー ボタンを追加します。 Describe it and drop it into the toolbar 配列を任意の位置に配置します。
1 2 3 4 5 6 7 8 9 10 11 | new MarkdownEditor('#markdown-editor', { toolbar: ['bold', 'italic', { custom: { title: 'Callout', icon: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20">…</svg>', action(editor) { editor.insertText('> [!NOTE]\n> Something worth noting'); } } }, 'preview'] }); |
の title はツールチップとボタンの CSS クラスになるため、これは次のようにスタイル設定できます。 .callout-btn、組み込みツールとまったく同じです。
いくつかのツール
好きなだけ追加してください。それぞれは配列内の独自のエントリであるため、個別に配置すると、一端にグループ化するのではなく、組み込みツールの間に配置できます。
1 2 3 4 5 6 7 | toolbar: [ 'bold', 'italic', { custom: { title: 'Callout', icon: svg1, action: insertCallout } }, 'ul', 'ol', { custom: { title: 'Signature', icon: svg2, action: insertSignature } }, 'preview' ] |
それぞれに明確な特徴を与える title。タイトルを共有する 2 つのツールは CSS クラスを共有し、クラスを持たないツールは CSS クラスを共有します。 .custom-btn.
オプション
| 財産 | タイプ | 目的 |
|---|---|---|
title | string | 必須。ツールヒントのテキスト、およびボタンの CSS クラスのソース。を通じて翻訳可能 labels. |
action | function | 必須。受信します (editor, event)。クリック イベントは渡されるため、ダイアログを開くツールはそれを次のユーザーに渡すことができます。 MarkdownEditor.modal. |
icon | string | ボタン面のインライン SVG。 |
shortcut | string | 次のようなキーボード ショートカット Ctrl+Shift+K。ツールチップに追加され、同じキーを使用する組み込みよりも優先されます。 |
何もないツール action ツールバーを壊すのではなく、コンソールの警告とともにスキップされます。ボタンは表示されません。 shortcut宣言した場合も登録されません。
コンテンツの操作
使用 editor.insertText() 自分でテキストエリアに書き込むのではなく。選択内容を置き換え、フォーカスを復元し、キャレットを移動し、スクロールし、プレビューを再レンダリングして起動します。 onChange。編集は通常のパスを経由するため、元に戻す機能は引き続き機能します。
1 2 3 4 5 6 7 8 | action(editor) { const textarea = editor.usertextarea; const selected = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd); const wrapped = `==${selected || 'highlight'}==`; // (text, where the caret lands, characters to leave outside the selection) editor.insertText(wrapped, wrapped.length, 0); } |
ショートカット
1 2 3 4 5 6 | { custom: { title: 'Highlight', icon: '<svg>…</svg>', shortcut: 'Ctrl+Shift+H', action: (editor) => editor.insertText('====', 2, 2) }} |
ツールチップが「ハイライト(Ctrl+Shift+H)」になります。ツールのショートカットは組み込みのショートカットよりも前にチェックされるため、エディターが処理する組み合わせをカスタム ツールが意図的に引き継ぐことができます。
独自のマークアップが必要なツール
ドロップダウンやダイアログは宣言的に記述することができないため、代わりにクラスを記述します。伸ばす MarkdownEditor.Tool、 セット this.button コンストラクター内で実装します applySyntax().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | class EmbedTool extends MarkdownEditor.Tool { constructor(editor) { super(editor, 'Embed video'); // tooltip, and .embed-video-btn this.shortcut = 'Ctrl+Shift+E'; // optional this.button = this.createButton('<svg>…</svg>'); } applySyntax(event) { const dialog = MarkdownEditor.modal(event, 'fj:max-w-sm', ` <input type="url" class="embed-url fj:me-input fj:w-full"> <button type="button" class="embed-go fj:me-btn fj:me-btn-sm">Insert</button> `, 'Embed'); dialog.querySelector('.embed-go').addEventListener('click', () => { const url = dialog.querySelector('.embed-url').value.trim(); if (url) this.editor.insertText(`\n<iframe src="${url}"></iframe>\n`); dialog.close(); }); } destroy() { // Called by editor.destroy(). Release anything you registered here. } } new MarkdownEditor('#markdown-editor', { toolbar: ['bold', EmbedTool, 'preview'] }); |
設定を渡す { tool: EmbedTool, config: {...} }、コンストラクターの 2 番目の引数として到着します。設定 this.button に null は何もレンダリングしません。これは、一部の構成にのみ適用されるツールに役立ちます。
注意すべき点が 1 つあります: Toolのコンストラクター呼び出し createButton()したがって、オーバーライドに必要なものはすべてそこから取得する必要があります this.editor、後で割り当てるフィールドからのものではありません super().
ダイアログヘルパー
MarkdownEditor.modal は、組み込みのリンク ツールと画像ツールが使用するダイアログであるため、入力を収集するツールは、独自のポップアップを作成するのではなく、エディターの残りの部分と同じように見えます。返されるのは、 <dialog> 要素はすでに開いており、フィールドをクエリして次で閉じます。 dialog.close().
1 2 | // (event, size classes, body HTML, aria label) const dialog = MarkdownEditor.modal(event, 'fj:max-w-sm', '…', 'Embed'); |
を渡す event あなたの applySyntax() 受け取った。ヘルパーはそれを読み取って、クリックがどのエディターから行われたのかを特定するため、ダイアログがそのエディターのラッパー内に追加され、そのテーマが選択されます。エディターで既に開いているダイアログを置き換え、閉じると DOM から自身を削除するため、クリーンアップするものは何もありません。
自分でマークダウンをレンダリングする
ツールにレンダリングされたコンテンツ (ツールチップ本体など) が埋め込まれている場合、 editor.renderMarkdown() プレビューとまったく同じように HTML を生成し、 renderer そして sanitizer.
const html = editor.renderMarkdown('**bold** text'); |
独自のテキストエリアのツールバー
ダイアログがリッチ テキストを収集する場合、ダイアログを再構築するのではなく、実際の書式設定ツールを提供します。ツールバーは、渡したテキストエリアにバインドされています。 labels が継承され、プレビューボタンは追加されません。
1 2 3 | const body = dialog.querySelector('textarea'); const bar = editor.createToolbar(body, ['bold', 'italic', 'strikethrough']); dialog.querySelector('.body-toolbar').appendChild(bar); |
これはツールバーの有効期間を管理しません。ボタンは、ダイアログが削除されるときにダイアログとともにクリーンアップされますが、ダイアログ内のツールがページ全体の何か (ドキュメント リスナーまたはタイマー) を登録している場合は、ダイアログが閉じるときに自分でそれを解放してください。
翻訳
カスタム ツールは、組み込みツールと同様に、指定したタイトルをキーとして翻訳されます。
labels: { 'Callout': 'Aviso', 'Embed video': 'Insertar video' } |
CSS クラスは影響を受けないため、 .callout-btn 滞在します .callout-btn あらゆる言語で。
📊 フッター (ステータスバー)
フッターはエディターの下にあり、カーソルの 行、列、ドキュメントの文字数、およびオプションで単語数が表示され、すべてリアルタイムで更新されます。これはデフォルトで表示され、各統計を個別に切り替えることができます。
| 鍵 | タイプ | デフォルト | 説明 |
|---|---|---|---|
line | boolean | true | 現在の行番号を表示します。 |
col | boolean | true | 現在の列番号を表示します。 |
chars | boolean | true | 総文字数を表示します。 |
words | boolean | false | 総単語数を表示します。デフォルトではオフ: に設定します true 有効にします。 |
使用例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | // Default — line, col, and chars visible new MarkdownEditor('#editor'); // Disable the footer entirely new MarkdownEditor('#editor', { footer: false }); // Hide only character count new MarkdownEditor('#editor', { footer: { chars: false } }); // Hide line and column, keep character count new MarkdownEditor('#editor', { footer: { line: false, col: false } }); // Show only line number new MarkdownEditor('#editor', { footer: { col: false, chars: false } }); // Enable word count alongside the defaults new MarkdownEditor('#editor', { footer: { words: true } }); // Show word count only new MarkdownEditor('#editor', { footer: { line: false, col: false, chars: false, words: true } }); |
🔀 編集モード
MarkdownEditor は、コンテンツを記述してフォーマットするための 2 つの異なる方法を提供します。従来の構文重視のビューと、視覚重視の最新のエクスペリエンスを切り替えることができます。
plain(デフォルト): クリーンで高性能な Markdown 環境。**bold**または# heading)が表示されます。開発者やマークダウン純粋主義者に最適hybrid: WYSIWYG にインスピレーションを得たエクスペリエンスで、基礎となる Markdown 構造を維持しながら、入力時に書式設定 (太字、斜体、見出し) をリアルタイムでレンダリングします。
1 2 3 4 5 6 7 8 9 10 11 12 | // Default initialization (Plain Mode) new MarkdownEditor('#markdown-editor'); // Explicit Plain Mode new MarkdownEditor('#markdown-editor', { mode: 'plain' }); // Hybrid (Visual) Mode new MarkdownEditor('#markdown-editor', { mode: 'hybrid' }); |
ハイブリッド モードとプレーン モードのプレビュー:
ハイブリッドモード
視覚的な書式設定は、入力中にリアルタイムでレンダリングされます。
プレーンモード (デフォルト)
軽量なエクスペリエンスを実現するために、生の Markdown 構文に焦点を当てています。
🌙 テーマ
MarkdownEditor は周囲のページからテーマを自動的に継承します。構成は必要ありません。編集者が読む data-theme 初期化時に最も近い祖先から取得されるため、すぐに使用できるサイトのテーマとの同期が保たれます。
テーマの解決方法(優先順位)
themeoption: オプション オブジェクトで渡される明示的なオーバーライドdata-themeで<textarea>: 要素に直接設定しますdata-theme任意の祖先: 例:<html>,<body>、またはラッパー<div>
利用可能なテーマ
'light' (デフォルト)、 'dark', 'snowberry', 'darkberry'
オプション 1、継承元 <html> または任意の祖先 (ゼロ構成)
1 2 3 4 5 6 | <html data-theme="dark"> ... <textarea id="markdown-editor"></textarea> <script> new MarkdownEditor('#markdown-editor'); // picks up dark automatically </script> |
オプション 2: 設定する data-theme 直接 <textarea>
1 2 3 4 | <textarea id="markdown-editor" data-theme="dark"></textarea> <script> new MarkdownEditor('#markdown-editor'); </script> |
オプション 3: 明示的 theme オプション (すべてを上書きします)
1 2 3 | new MarkdownEditor('#markdown-editor', { theme: 'dark' }); |
🎨 CSS変数によるカスタムテーマ
エディターの CSS 変数をオーバーライドすることで、エディターの外観を完全にカスタマイズできます。 .markdown-editor-wrapper 要素または任意の [data-theme] セレクタ。すべての色で使用されているのは、 OKLCH色空間 知覚的に均一な結果が得られます。
| 変数 | 目的 | ライトデフォルト | ダークデフォルト |
|---|---|---|---|
--color-base | 編集者の背景 | oklch(100% 0 0) | oklch(10.9% 0 0) |
--color-on-base | 主要なテキストの色 | oklch(22% 0 0) | oklch(98% 0 0) |
--color-primary | プライマリアクセント (ツールバーがアクティブ、リンク) | oklch(51.1% .262 277) | oklch(66.4% .184 286) |
--color-on-primary | 原色の表面上の文字 | oklch(96.2% .018 272) | oklch(10% .01 270) |
--color-secondary | 第二アクセント | oklch(59.1% .293 323) | oklch(65% .18 220) |
--color-accent | 強調表示アクセント (インライン コード、斜体) | oklch(54.1% .281 293) | oklch(75% .18 50) |
--color-neutral | ニュートラルなサーフェス(境界線、仕切り) | oklch(15% 0 0) | oklch(85% 0 0) |
--color-error | エラー状態の色 | oklch(57.7% .245 27) | oklch(60% .22 30) |
--border-radius | エディターフレームの角丸め | 0.25rem |
カスタムテーマの例
任意の変数をオーバーライドします .markdown-editor-wrapper エディターの初期化後、またはカスタム定義 [data-theme] スタイルシート内のブロック:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | /* Override individual variables */ .markdown-editor-wrapper { --color-primary: oklch(60% 0.2 30); /* orange accent */ --border-radius: 0.5rem; } /* Or define a full custom theme */ [data-theme="brand"] .markdown-editor-wrapper, .markdown-editor-wrapper[data-theme="brand"] { --color-base: oklch(15% 0.01 250); --color-on-base: oklch(95% 0 0); --color-primary: oklch(65% 0.22 145); /* green */ --color-on-primary: oklch(10% 0 0); --color-accent: oklch(75% 0.18 60); --color-neutral: oklch(80% 0 0); --border-radius: 0.75rem; } |
new MarkdownEditor('#markdown-editor', { theme: 'brand' }); |
🌐 インターフェース言語
エディター独自のテキスト、ツールヒント、メニュー項目、モーダル フィールドおよびボタンは、デフォルトでは英語です。渡す labels それを翻訳するオブジェクトです。キーは英語の文字列であり、gettext の動作方法であるため、変更したいものだけをリストし、不足しているものは英語に戻ります。
1 2 3 4 5 6 7 8 9 10 11 12 13 | new MarkdownEditor('#markdown-editor', { labels: { 'Bold': 'Gras', 'Italic': 'Italique', 'Heading': 'Titre', 'Link': 'Lien', 'Image link': 'Lien de l\'image', 'URL': 'URL', 'Alt text': 'Texte alternatif', 'Apply': 'Appliquer', 'Uploading...': 'Téléversement...', }, }); |
これは、右から左へのコンテンツと並んで最も重要です。アラビア語、ウルドゥー語、ペルシア語は単独で正しくレイアウトされますが、右から左へ記述するテキストの上に「太字」と表示されたままのツールバーは半分しか翻訳されていません。
🏷 変数
プレースホルダーを挿入するためのツールバー ドロップダウンを追加します。電子メール、請求書、契約書のテンプレートなど、ドキュメントの作成者がプレースホルダー構文を定義した開発者ではない場合に便利です。読みやすい名前を選択すると、正しい構文が挿入されます。
1 2 3 4 5 6 7 8 9 | new MarkdownEditor('#markdown-editor', { toolbar: ['bold', 'italic', 'link', { variables: [ { label: 'Customer Name', value: '{{customer.name}}' }, { label: 'Invoice No', value: '{{invoice.number}}' } ]}, 'preview' ] }); |
ツールはインラインで構成されます。 toolbar 配列なので、他のボタンとの位置はあなた次第です。ボタンにはラベルがリストされ、ラベルをクリックするとそのラベルが挿入されます。 value カーソルで、選択内容を置き換えます。リストが空の場合は何も表示されません。
プレビューのサンプル値
与えられたエントリ sample は、そのサンプルをプレビューに表示しますが、テキストエリアには実際のプレースホルダーが保持されます。どちらかが含まれていないエントリは書かれたとおりに表示されるため、両方を混合することができます。
1 2 3 4 5 6 7 | { variables: [ { label: 'Customer Name', value: '{{customer.name}}', sample: 'Hannes' }, { label: 'Invoice No', value: '{{invoice.number}}' } ]} // textarea : Hi {{customer.name}}, invoice {{invoice.number}} // preview : Hi Hannes, invoice {{invoice.number}} |
グループ化
エントリーをする items の代わりに value 見出しセクションをレンダリングします。グループ化されたエントリとフラットなエントリを 1 つのリストに混在させることができます。
1 2 3 4 5 6 7 8 9 10 | { variables: [ { label: 'Today', value: '{{today}}', sample: '10 September 2026' }, { label: 'Customer', items: [ { label: 'Name', value: '{{customer.name}}', sample: 'Hannes' }, { label: 'Email', value: '{{customer.email}}', sample: 'hannes@example.com' } ]}, { label: 'Invoice', items: [ { label: 'Number', value: '{{invoice.number}}' } ]} ]} |
知っておくべきこと
- エディターは変数を解決しません。 エディターはテキストを挿入し、アプリケーションは後で (通常はサーバー側で) 実際の値を置き換えます。
sampleプレビューの表示内容にのみ影響します。 - ラベルはプレーン テキストとして表示されるため、ラベル内のマークアップは表示されません。
- 不正な形式のエントリはスローされるのではなくスキップされます。使用可能なものが何も設定されていない場合、ボタンはまったく表示されません。
🖋 カスタムレンダラー
プレビューは次のようにレンダリングされます。 マークされた そして消毒した DOMPurify。どちらも交換可能です。アプリケーションがすでに別のライブラリを使用してマークダウンをレンダリングしており、プレビューを本番環境と正確に一致させたい場合に、これを使用します。
どちらのオプションも文字列を受け取って文字列を返す単純な関数であるため、どのパーサーやサニタイザーでも機能します。
1 2 3 4 5 6 7 8 9 | import MarkdownIt from 'markdown-it'; import taskLists from 'markdown-it-task-lists'; import MarkdownEditor from 'markdown-text-editor'; const md = new MarkdownIt({ linkify: true, breaks: true }).use(taskLists); new MarkdownEditor('#markdown-editor', { renderer: markdown => md.render(markdown) }); |
DOMPurify は引き続き出力上で実行されるため、何も設定せずに XSS 保護を維持できます。
カスタム消毒剤
レンダラーが出力するものをデフォルトで削除する場合にのみ必要です。 DOMPurify は削除します <iframe> デフォルトでは、ビデオ埋め込みは明示的に許可する必要があります。 DOMPurify は、エディターにバンドルされているコピーが内部にあるため、独自のコードにインポートする必要があります。
1 2 3 4 5 6 7 8 9 | import DOMPurify from 'dompurify'; new MarkdownEditor('#markdown-editor', { renderer: markdown => md.render(markdown), sanitizer: html => DOMPurify.sanitize(html, { ADD_TAGS: ['iframe'], ADD_ATTR: ['allow', 'allowfullscreen', 'frameborder'] }) }); |
バンドラーの代わりにスクリプト タグを使用して、エディターと一緒に DOMPurify を読み込みます。
1 2 | <script src="https://cdn.jsdelivr.net/npm/dompurify"></script> <script src="https://cdn.jsdelivr.net/npm/markdown-text-editor"></script> |
知っておくべきこと
- プレビューのみ。 ハイブリッド モードのライブ フォーマットは別の内部レンダラーを使用するため、影響を受けません。
- タスク リストにはプラグインのサポートが必要です。 クリック可能なチェックボックスは、次の検索によって見つかります。
input[type="checkbox"]出力にはマークダウンが必要ですmarkdown-it-task-lists。エディターは、タスク リスト構文が検出され、チェックボックスが検出されない場合、警告をログに記録します。 - 両方とも同期である必要があります。文字列を返します。アン
async関数の書き込み[object Promise]プレビューに入ります。 - サニタイザーを交換すると、保護が置き換えられます。 などのパススルー
html => htmlサニタイズを完全に無効にし、完全に信頼できるコンテンツに対してのみ安全です。
🎨 内部要素のスタイル設定
CSS 変数は継承するため、ほとんどのテーマをカバーするため、CSS 変数をオンに設定すると、 .markdown-editor-wrapper ツールバー、ボタン、プレビュー、フッターに到達します。必要なものを公開する変数がない場合にのみ、クラス名にアクセスしてください。
1 2 3 4 5 | /* Variables set on the wrapper inherit down to every child */ .markdown-editor-wrapper { --border-radius: 12px; /* rounds the editor and its toolbar buttons */ --color-primary: oklch(60% 0.2 30); } |
クラスリファレンス
これらのクラス名は安定しており、安全にスタイル設定できます。
| クラス | 要素 |
|---|---|
.markdown-editor-wrapper | エディタ全体を包む外側のコンテナ |
.toolbar | 編集領域の上のツールバー ストリップ |
.markdown-btn | 個別のツールバーボタン |
.preview-btn | プレビュー/全画面切り替えボタン |
.editor-layout | 編集領域とプレビューを並べて保持するグリッド |
.textarea-wrapper | 編集領域の周囲のラッパー |
.editor-textarea | 基礎となる textarea 要素 |
.display-layer | レンダリングされた書式設定レイヤー、ハイブリッド モードのみ |
.preview-wrapper | プレビュー列 |
.preview-content | プレビュー内のレンダリングされたマークダウン |
.editor-footer | エディターの下のステータスバー |
.find-replace-panel | パネルを見つけて交換する |
1 2 3 4 5 6 7 8 9 10 | /* Some variables are set by the component on itself, which beats an inherited value. Target the element directly for those. */ .markdown-editor-wrapper .markdown-btn { --btn--font-size: 0.875rem; } /* And use classes for anything no variable exposes */ .markdown-editor-wrapper .toolbar { border-bottom: 2px solid oklch(60% 0.2 30); } |
1人の編集者をターゲットにする
1 ページに複数のエディタがある場合、そのうちの 1 つを次のようにターゲットにします。 data-editor。ラッパーはその ID をミラーリングします。 <textarea>、 それで <textarea id="notes"> あなたに与えます [data-editor="notes"]。 ID 自体はテキストエリアに残るため、 getElementById 働き続けます。
1 2 3 4 | /* one editor only */ [data-editor="notes"] { --border-radius: 0; } |
🪟 フルスクリーンとレイヤー化 (z-index)
全画面表示でエディターが使用するのは、 z-index: 10000、ほとんどの UI フレームワークが固定ヘッダーとオーバーレイ用に予約しているレイヤーをクリアします。固定ヘッダーまたはサイドバーが依然としてエディターを覆っている場合は、この値を上げます。
でオーバーライドします --mte-fullscreen-z-index。この値はフルスクリーンでのみ適用され、継承されるため、任意の祖先に設定すると、その下のすべてのエディタがカバーされます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | /* every editor on the page */ .markdown-editor-wrapper { --mte-fullscreen-z-index: 20000; } /* one section only - the value inherits down */ #admin-panel { --mte-fullscreen-z-index: 20000; } /* a single editor, by its textarea id */ [data-editor="notes"] { --mte-fullscreen-z-index: 20000; } |
コンテンツAPI
MarkdownEditor の中核的な強みの 1 つは、基礎となる要素を保持していることです。 <textarea> 完全に同期しています。最新の JavaScript フレームワークを使用している場合でも、Django、PHP、Laravel などの従来のバックエンドを使用している場合でも、ワークフローはシンプルかつネイティブのままです。
コンテンツの読み取りと書き込み
1\。ネイティブの方法 (推奨)
エディターは標準のテキストエリアを拡張するため、使い慣れた DOM メソッドを使用できます。これは、新しい API を学習せずにデータを操作する最も速い方法です。
1 2 3 4 5 | // Retrieve content via ID const markdown = document.getElementById('markdown-editor').value; // Set content via ID (The editor UI updates automatically) document.getElementById('markdown-editor').value = "# New Heading Content"; |
2\。変数参照の使用
textarea 要素への参照がある場合は、それを直接使用できます。ライブラリ固有の API は必要ありません。
1 2 3 4 5 6 7 | const textarea = document.getElementById('markdown-editor'); // Retrieve content const markdown = textarea.value; // Set content (the editor UI reflects this immediately) textarea.value = "## Updated via JS"; |
3\。サーバー側の初期コンテンツの設定
初期コンテンツを直接設定する推奨方法は、 <textarea> HTML: これはあらゆるバックエンド フレームワーク (Django、Laravel、Rails、PHP など) で自然に動作し、エディターが init 時に自動的にレンダリングします。
1 2 | <!-- Recommended: set content server-side --> <textarea id="markdown-editor"># Hello World</textarea> |
実行時にコンテンツを読み取りまたは更新するには、ネイティブの textarea 価値。電話 editor.render() 更新後にプレビューとハイブリッド レイヤーを更新します。
1 2 3 4 5 6 7 8 | const textarea = document.getElementById('markdown-editor'); // Read const markdown = textarea.value; // Update at runtime textarea.value = '# New content'; editor.render(); |
4\。エディターを破棄します。 destroy()
電話 editor.destroy() エディターの DOM ラッパーを削除し、元の DOM ラッパーを復元します。 <textarea> ドキュメント内の位置に移動します。単一ページのアプリケーションでビューをアンマウントするときに便利です。
1 2 3 4 | const editor = new MarkdownEditor('#markdown-editor'); // Remove the editor and restore the plain textarea editor.destroy(); |
変化に対応する onChange
渡す onChange コンテンツが変更されるたびに通知を受けるコールバック。現在のマークダウン文字列を受け取ります。
1 2 3 4 5 | const editor = new MarkdownEditor('#markdown-editor', { onChange(value) { console.log('Content changed:', value.length, 'characters'); } }); |
ドラフトの自動保存 localStorage
使用 onChange キーストロークごとに下書きを保存します。エディタを初期化する前にテキストエリアを事前に入力して復元します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | const DRAFT_KEY = 'my-page-draft'; // Restore saved draft before init (only if textarea starts empty) const textarea = document.getElementById('markdown-editor'); const saved = localStorage.getItem(DRAFT_KEY); if (saved && !textarea.value) textarea.value = saved; // Save on every change const editor = new MarkdownEditor('#markdown-editor', { onChange(value) { localStorage.setItem(DRAFT_KEY, value); } }); // Clear draft after successful form submission document.querySelector('form').addEventListener('submit', () => { localStorage.removeItem(DRAFT_KEY); }); |
フォームの送信
MarkdownEditor はネイティブ上に直接構築されているため、 <textarea>すべてのバックエンドフレームワーク( Django、Laravel、PHP、Ruby on Railsなど)と互換性があります。
ここは「ネイティブファースト」の哲学が輝く場所です。フォームを送信する前にデータを手動で同期する必要はありません。ブラウザは、エディタを標準入力フィールドとまったく同じように扱います。
1 2 3 4 5 6 7 8 9 10 11 12 | <form method="POST" action="/api/submit"> <textarea id="markdown-editor" name="content" class="h-48" rows="5"> # Initial Content </textarea> <button type="submit">Submit to Server</button> </form> <script> // Just initialize it. That's it. new MarkdownEditor('#markdown-editor'); </script> |
注: MarkdownEditorプラグインの初期化は必須です
標準のHTMLを使用するだけです <form>The name textareaの属性は、サーバーがコンテンツを識別するために使用するものです。
バックエンドのゲームチェンジャーである🚀理由
エディタはネイティブを保持するため <textarea> サーバーはデータを標準文字列として処理します。余分なロジックは必要ありません:いいえ preventDefault() マニュアルなし FormData 構造
これが「キラー機能」である💡理由:
ほとんどのエディタ( Quill、Editor.js、simpleMDE、easyMDEなど)は、複雑なJSON構造でデータを保存します。開発者がこれらを使用する場合、データベーススキーマとレンダリングロジックを書き換える必要があります。
** MarkdownEditor **を使用すると、開発者は古いWebサイトを取得し、プレーンを置き換えることができます。 <textarea> バックエンドはそれが変更されたことを認識していません。いつもと同じ生のテキストを受け取るだけですが、ユーザーは10倍優れたエクスペリエンスを得ます。
| フレームワーク/言語 | Markdownコンテンツへのアクセス方法 |
|---|---|
| PHP | $_POST['content'] |
| ジャンゴ | request.POST.get('content') |
| node.js express | req.body.content |
| ララベル | $request->input('content') |
| ルビー・オン・レール | params[:content] |
🖼️ 高度な画像アップロード
画像のアップロードをネイティブに処理する:低速でメモリ負荷の高いBase 64文字列に依存するのではなく、パフォーマンスとSEOの両方にとって大きな勝利です。
貼り付けてドロップ
スクリーンショットを貼り付けるか、画像ファイルをエディターにドラッグすると、ツールバーボタンと同じエンドポイントを介してアップロードされます。プレースホルダーがすぐに表示されるため、エディターがフリーズすることはなく、アップロードが完了すると実際のパスに置き換えられます。アップロードに失敗すると、プレースホルダーは静かに消えるのではなく、目に見えるマーカーに置き換えられます。
これには uploadUrl 以下に構成されています。それがなければ、画像を貼り付けることは何もなく、エディタは何を追加するかを説明する警告をログに記録します。これは、代替案がデータベースのBase 64文字列になるためです。
複数のファイルが一度に1つずつアップロードされるため、画像は到着した順序で表示されます。
設定オプション
画像ツールは、 fileInput 直接のサーバーアップロードを処理するための設定。
accept:許可されている画像フォーマットの配列を定義します(例: 'webp ',' avif ')uploadUrl:バックエンドエンドポイントを指定します。Fileオブジェクトはを介して送信されますPOSTparams:画像ファイルと一緒に追加データ( CSRFトークン、ユーザーID、フォルダー名など)を送信するためのオプションのオブジェクト
使用例(フルコンフィグ)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | const options = { placeholder: 'Start writing...', toolbar: [ 'link', { image: { fileInput: { accept: ['webp', 'avif'], // restrict the image upload format uploadUrl: '/api/upload', // Your upload endpoint params: { _token: 'your_csrf_token_here', // Essential for Laravel/Django folder: 'blog_posts' } }, // Supports boolean: true/false OR object: { required: true } altInput: { required: true } } }, 'preview' ], } const editor = new MarkdownEditor('#markdown-editor', options); |
📡 サーバー統合
リクエストを送信します。
エディターは次のメッセージを送信します。 POST としてリクエストする multipart/form-data。デフォルトでは、次のものが含まれます。
image_file:実際のファイルオブジェクトimage_alt:ユーザーが入力した代替テキスト -...に定義されている任意のカスタムデータを加えてparamsオブジェクト
必要な対応
正常にアップロードされたことを確認し、エディターに画像を挿入するには、サーバーは次のJSON構造を返す必要があります。
1 2 3 4 | { "success": true, "image_path": "https://cdn.yourdomain.com/uploads/image.webp" } |
注意:必ずキーを使用してください image_path アップロードされた画像のURL。
戻ることもできます image_altこれは、ユーザーがaltフィールドを空のままにした場合にのみ提案として使用されます。彼らが自分で入力したものは常に勝利するので、ファイル名や画像認識からaltテキストを派生させるサーバーは、実際の説明を上書きすることなくそれを提供することができます。
1 2 3 4 5 | { "success": true, "image_path": "https://cdn.yourdomain.com/uploads/image.webp", "image_alt": "Two people looking at a laptop" } |
失敗したら、戻る success: false with an error または message 文字列。そのテキストはユーザーに表示されるため、ユーザーが操作できるようにします。
画像代替テキスト検証(altInput)
コンテンツがアクセス可能でSEOに優しい状態を維持するために、** MarkdownEditor **はデフォルトで代替テキスト検証を強制します。
- ** Default Behavior **: If
altInput定義されていません。デフォルトは{ required: true } - アクセシビリティの強制: altの説明が提供されるまで、ユーザーが画像を挿入することはできません
1 \。デフォルト(設定は必要ありません)
1 2 3 4 | // Alt text is REQUIRED by default image: { fileInput: { uploadUrl: '/api/upload' } } |
2.速記(検証を無効にする)
説明のない画像を許可する場合は、ブール値を次のように設定します。 false.
1 2 3 | image: { altInput: false // Users can now skip the alt text field } |
3.オブジェクトベース(明示的)
1 2 3 4 5 | image: { altInput: { required: false // Disables alt text validation — users can skip the alt field } } |
標準画像使用量(いいえ fileInput)
状況 fileInput 設定されていない場合、エディタはデフォルトで単純なURLベースのモーダルになります。これは、ユーザーが主に外部の画像ホストにリンクしている場合に理想的です。
1 2 3 4 5 6 7 8 | const options = { toolbar: [ 'link', 'image', 'preview' ], } const editor = new MarkdownEditor('#markdown-editor', options); |
パラメータを使用する💡メリットは?
LaravelやDjangoなどのフレームワークでは、CSRFトークンなしでファイルをアップロードすることはできません。 _token になります。 params リクエストはバックエンドのセキュリティミドルウェアをシームレスに通過し、サーバー側コントローラーの「ゼロロジック」の哲学を維持します。
キーボードショートカット
一般的な書式設定アクションは、ツールバーに触れることなく、キーボードから直接トリガーできます。各ショートカットは、対応するツールバーボタンのツールチップにも表示されます。
| ショートカット | 行うべきこと |
|---|---|
Ctrl + B / ⌘ B | 切り替え: 太字 |
Ctrl + I / ⌘ I | 切り替え: イタリック |
Ctrl + K / ⌘ K | リンクを挿入 |
Ctrl + ` / ⌘ ` | インライン切り替え Code |
Ctrl + Shift + S / ⌘ ⇧ S | トグル |
Ctrl + 1 / ⌘ 1 | 見出し1 |
Ctrl + 2 / ⌘ 2 | 見出し2 |
Ctrl + 3 / ⌘ 3 | 見出し3 |
Ctrl + L / ⌘ L | 箇条書きリストを切り替える |
Ctrl + Z / ⌘ Z | 取り消し |
Ctrl + Shift + Z / ⌘ ⇧ Z | やり直し |
Tab | 選択した行をインデント |
Shift + Tab | 選択した行をインデント解除 |
Ctrl + F / ⌘ F | 検索パネルを開く |
Ctrl + H / ⌘ H | 検索と置換パネルを開く |
Ctrl + Shift + F / ⌘ ⇧ F | フルスクリーン表示の切り替え |
F11 | フルスクリーン表示の切り替え |
Escape | 検索パネルを閉じる/全画面プレビューを終了する |
検索と置換
エディター内には組み込みの検索と置換パネルがあります。ブラウザーの拡張機能や個別のツールは必要ありません。
プレス記事 Ctrl + F または ⌘ F)をクリックして** Find パネルを開きます
プレス記事 Ctrl + H または ⌘ H)をクリックして Find & Replace パネルを開きます
-検索は大文字と小文字を区別しない**で、ライブマッチカウンターを表示します(例:* 3/12 *)
- **/**ボタンを使用して一致▲を▼ナビゲートするか、
Enter/Shift + Enter - ** Replace は現在のハイライトされた一致を置き換えます。 Replace All **はすべてのオカレンスを一度に置き換えます
プレス記事
Escapeパネルを閉じてエディタにフォーカスを戻します
パネルはエディターコンテンツエリアの右上隅に浮かび、書き込みを中断しません。
貼り付けられたURLからの🔗リンク
テキストを選択し、その上にURLを貼り付けると、選択したURLではなくマークダウンリンクが表示されます。
1 2 | Read the docs <- select "the docs", paste https://example.com Read [the docs](https://example.com) <- what you get |
規則は意図的に厳格です:ほんのわずかな http または https 空白のないURLはこのように扱われます。URLが含まれている文章を貼り付けるか、何も選択されていない状態で貼り付けると、通常の貼り付けのように動作します。
特長
🔌 ネイティブフォームの統合
標準とまったく同じように動作します <textarea>。複雑なAPIはありません。 value または name 属性。PHP、Django、またはNode.jsでの標準的なHTMLフォームの送信で「ちょうど動作」します。
🖼️ 高度な画像アップロード
API経由でネイティブサーバーのアップロードを構成します。重いBase 64文字列を避けて、独自のCDNで画像をホストすることで、ページの読み込みを高速化し、優れたSEOを確保します。
🔀 ハイブリッドモードとプレーンモード
を切り替える ハイブリッド( WYSIWYG ) ビジュアル編集の経験、または プレーン・マークダウン 伝統的なコーディング感覚のためのモード。
高性能
A 53 KB gzip バンドル( 252 KB縮小、CSSを含む)は、「ヘビーコンテンツ」に最適化されています。"入力の遅れやパフォーマンスの低下なしに、大量のドキュメントや大きなファイルを処理します。プレビューの更新、キャッシュされたスタイルの計算、および競合のないキーボードの処理を発表しました。そのため、TabとEnterは常に1つのことを行います。
🌍 組み込みのRTLサポート
アラビア語、ウルドゥー語、ペルシア語などの右から左への言語のネイティブサポート。グローバルにアクセス可能なアプリケーションの構築に最適です。
シンタックスハイライト
明確なコードとマークダウン形式により、読みやすさが向上しました。
🌙 アダプティブテーマ
ダークモードの自動サポートが含まれています。それはあなたのシステム設定または Frutjam UI シームレスなビジュアルエクスペリエンスのためのライブラリ。
📝 スマート編集
順序付きリスト、順序なしリスト、チェックリストのGitHubスタイルの自動リスト継続:押す Enter エディターはパターンを続行します。プレビューペインのチェックボックスはクリック可能で、マークダウンソースに即座に同期されます。
完全レスポンシブ
外出先で編集するためのデスクトップ、タブレット、スマートフォンに完璧に適応する、流動的なモバイルファーストのUI。
ユニバーサルなバンドサポート
互換性: ESM、UMD、CommonJS、LIFE。CDNを介して箱から出して動作します(<script src>)、npm、または任意のバンドル( Vite、webpack、Rollup ) :追加の設定は必要ありません。
デフォルトで♿アクセス可能
ARIAのフルサポートが組み込まれています:ツールバーのランドマーク、ラベル付きプレビュー領域、スクリーンリーダーに優しいボタン、 aria-pressed プレビュートグルで、 disabled そして aria-disabled 非アクティブなツールで、モーダルが閉じたときにフォーカスの復元を修正します。
CSSの競合🛡️ゼロ
エディタースタイルのスコープは完全に .markdown-editor-wrapper。Tailwindのグローバルプリフライトは除外されるため、エディターはスタイルを壊すことなく、Bootstrap、Tailwind、またはその他のフレームワークと一緒に安全に暮らします。
キーボードショートカット
Ctrl+B, Ctrl+I, Ctrl+K, Ctrl+`, Ctrl+Shift+S:マウスをタッチせずに一般的な書式設定アクション。各ショートカットは、ツールバーボタンのツールチップに表示されます。
検索と置換
プレス記事 Ctrl+F を見つけるか、 Ctrl+H 検索と置換を開きます。ライブマッチカウンター、次/前のナビゲーション、単一置換、およびすべて置換による大文字と小文字を区別しない検索:エディタを離れることなく。
🔒 XSSセーフプレビュー
レンダリングされたプレビューは、 DOMPurify dOMに書き込まれる前に。スクリプトタグ、インラインイベントハンドラー、および不正なマークダウン入力の悪意のあるURLは自動的に削除されます。設定は必要ありません。
▶️ リアルタイムプレビュー
入力するとすぐにマークダウンが表示されます。
容易な統合:
最小限のセットアップで、あらゆるWebプロジェクトにシームレスに統合できます。
🛠️ カスタマイズ可能なツールバー
太字、斜体などのツールバーオプションを動的に設定して並べ替えます。
レイアウト例
この包括的な例を使用して、カスタムツールバーの並べ替えや高度な画像アップロード処理など、すべての主な機能を備えた** MarkdownEditor **を初期化します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | const editor = new MarkdownEditor('#markdown-editor', { mode: 'hybrid', placeholder: 'Start writing...', footer: { line: true, col: true, chars: true, words: true, }, onChange(value) { console.log('Content updated:', value.length, 'characters'); }, labels: { 'Bold': 'Gras', 'Italic': 'Italique', 'Uploading...': 'Téléversement...', }, toolbar: [ 'heading', 'bold', 'italic', 'strikethrough', 'blockquote', 'ul', 'ol', 'checklist', 'code', 'codeblock', 'hr', 'table', { image: { fileInput: { accept: ['webp', 'avif', 'png'], uploadUrl: '/api/upload' } } }, 'link', 'undo', 'redo', 'indent', 'outdent', 'preview' ], }); // Read content natively const markdown = document.getElementById('markdown-editor').value; // destroy() when the view unmounts (SPAs) // editor.destroy(); |
これは役に立ちましたか?
GitHubスターは、他の開発者がエディターを発見するのに役立ちます。これはの一部です フルッチャム。そこにある星も役に立ちます。