ノートエディタ
左にノート一覧、右に contenteditable のブロック本文。空のブロックで「/」を打つとブロックメニュー(見出し/箇条書き/区切り/本文)が出て、Enter で次のブロックへ進む。
プレビュー
入力
操作実際に入力して試せます。
デザインの要点
- 本文はブロックの縦積み。段落・見出し・箇条書きを同じ 1 行の器で扱うと、書く速度が落ちない
- 「/」のメニューは入力位置の直下に出し、↑↓と Enter で選べる。マウスに持ち替えさせない
- 装飾ツールバーは常設しない。書いているときに見えるのは文字と薄いプレースホルダーだけ
- 左の一覧は題と更新日だけ。本文の抜粋を出すと一覧が本文と競合して読みにくくなる
プロのサイトでの実例
実例は「型の使われ方」の観察であり、コード・ロゴの転載ではありません。サイト側の更新で見え方が変わることがあります。
実装メモ
contenteditable の内容はプレビュー内のメモリにだけ保存します。実装では blur や一定間隔で保存し、IME 変換中(compositionstart〜compositionend)は Enter を横取りしないよう isComposing を確認してください。
コード(コピーして使えます)
<div class="ne-app">
<aside class="ne-side">
<div class="ne-side-head"><span class="ne-ws">ミナト工房</span><button type="button" class="ne-new" id="ne-new" aria-label="新しいノート">+</button></div>
<ul class="ne-notes" id="ne-notes"></ul>
</aside>
<main class="ne-main">
<button type="button" class="ne-side-toggle" id="ne-side-toggle" aria-expanded="false" aria-controls="ne-notes">ノート一覧</button>
<div class="ne-doc" id="ne-doc">
<h1 class="ne-title" id="ne-title" contenteditable="true" spellcheck="false" data-placeholder="無題"></h1>
<div class="ne-blocks" id="ne-blocks"></div>
</div>
<div class="ne-menu" id="ne-menu" role="listbox" aria-label="ブロックの種類" hidden>
<button type="button" class="ne-menu-item is-active" role="option" data-type="h2"><span class="ne-menu-ic">H</span><span><span class="ne-menu-name">見出し</span><span class="ne-menu-sub">大きめの見出し</span></span></button>
<button type="button" class="ne-menu-item" role="option" data-type="li"><span class="ne-menu-ic">•</span><span><span class="ne-menu-name">箇条書き</span><span class="ne-menu-sub">点付きのリスト</span></span></button>
<button type="button" class="ne-menu-item" role="option" data-type="hr"><span class="ne-menu-ic">—</span><span><span class="ne-menu-name">区切り線</span><span class="ne-menu-sub">セクションを分ける</span></span></button>
<button type="button" class="ne-menu-item" role="option" data-type="p"><span class="ne-menu-ic">¶</span><span><span class="ne-menu-name">本文</span><span class="ne-menu-sub">ふつうの段落</span></span></button>
</div>
</main>
</div>