@rabee-org/svelte-livedown
v0.1.0
Published
A WYSIWYG Markdown editor component for Svelte
Readme
@rabee-org/svelte-livedown
WYSIWYG Markdown エディタコンポーネント for Svelte 5。
CodeMirror 6 ベースの Live Preview 方式で、カーソル行では Markdown 構文を表示し、離れると整形表示に切り替わります。
Demo: https://svelte-livedown.vercel.app
Install
npm install @rabee-org/svelte-livedownUsage
<script>
import { Livedown } from '@rabee-org/svelte-livedown';
let content = $state('');
</script>
<Livedown bind:value={content} />textarea の代わりに置くだけで Markdown エディタとして機能します。
Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| value | string | '' | Markdown コンテンツ(bind:value で双方向バインド可) |
| placeholder | string | '' | エディタが空のときに表示するプレースホルダー |
| toolbar | boolean | true | フォーマットツールバーの表示/非表示 |
| editable | boolean | true | エディタの編集可否 |
| class | string | '' | 外側コンテナに追加する CSS クラス |
| contentClass | string | '' | エディタ内部 (.cm-content) に追加する CSS クラス |
| onchange | (value: string) => void | - | Markdown が変更されたときのコールバック |
| onUploadImage | (file: File) => Promise<string> | - | 画像が貼り付け / ドロップされた時に呼ばれる。解決した URL が  として挿入される |
Features
Live Preview
カーソルがある行は Markdown 構文がそのまま表示され、離れると整形表示に切り替わります。
# 見出し ← カーソルがない行では # が非表示になり、大きな見出しとして表示
**太字テキスト** ← ** が非表示になり、太字として表示対応フォーマット
- テキスト装飾 — 太字、斜体、取り消し線、インラインコード
- 見出し — H1 〜 H3
- リスト — 箇条書き、番号付き、タスクリスト(チェックボックス)
- 構造 — 引用、コードブロック(構文ハイライト付き)、水平線
- リンク — 通常リンク、GFM の bare URL オートリンク
- 画像 —
がインラインで表示される - テーブル — GFM テーブル。セルをクリックして直接編集でき、
+ボタンで行 / 列を追加 - テキスト配置 — 中央寄せ / 右寄せ(
<div align="...">記法)
キーボードショートカット
| ショートカット | アクション |
|--------------|-----------|
| Cmd+B | 太字 |
| Cmd+I | 斜体 |
| Cmd+E | インラインコード |
| Cmd+Shift+X | 取り消し線 |
| Tab / Shift+Tab | リスト項目のインデント / アウトデント |
| Cmd+Z / Cmd+Shift+Z | Undo / Redo |
ツールバー
toolbar prop で表示/非表示を切り替え可能。太字・斜体・見出し・リスト・引用・コードブロック・リンク・水平線のボタンを提供します。
タスクリスト
- [ ] / - [x] 記法に対応。カーソルが離れるとチェックボックスウィジェットとして表示され、クリックでトグルできます。
URL の貼り付け
テキストを選択した状態で URL を貼り付けると [選択テキスト](URL) として挿入されます。選択がない場合はそのまま貼り付け(GFM のオートリンクで描画)。
画像のアップロード(貼り付け / ドロップ)
onUploadImage prop にアップローダを渡すと、クリップボードからの貼り付けとファイルのドラッグ&ドロップの両方で呼ばれ、返された URL が  として挿入位置に埋め込まれます。
<script>
import { Livedown } from '@rabee-org/svelte-livedown';
let content = $state('');
async function uploadImage(file) {
const form = new FormData();
form.append('file', file);
const res = await fetch('/api/upload', { method: 'POST', body: form });
const { url } = await res.json();
return url;
}
</script>
<Livedown bind:value={content} onUploadImage={uploadImage} />未指定の場合、画像の貼り付け / ドロップは無視されます。複数画像にも対応(改行区切りで挿入)。
テキスト配置
段落にカーソルを置いてツールバーの ≡(中央寄せ)/ ⟶(右寄せ)をクリックすると、<div align="..."> で囲まれます。もう一度同じボタンを押すと解除、別方向を押すと切替。
raw markdown は CommonMark 準拠のマルチライン形式で出力されるため、内側の markdown 装飾(太字、見出し等)もそのまま保持されます。
<div align="center">
**太字** や *斜体* もそのまま効く
</div>エディタ上はカーソルがブロック内にある時だけ <div> / </div> タグ行が見え、外すと完全に隠れて中身の段落だけが残ります。
Styling
CSS クラスで上書き
<Livedown class="my-editor" bind:value={content} />
<style>
:global(.my-editor .cm-content) {
padding: 16px;
font-size: 14px;
}
</style>Tailwind CSS
contentClass prop で .cm-content に直接クラスを渡せます。CM6 のデフォルトスタイルより詳細度が低いため、! プレフィックスが必要な場合があります。
<Livedown contentClass="!p-4 !text-sm" bind:value={content} />Requirements
- Svelte 5
- SvelteKit 2 (recommended)
License
MIT
