Web上に付箋を絵馬のように貼って並べる、フレームワーク非依存のTypeScriptライブラリ。
付箋の作成・編集・自由配置・接続線描画を提供する。1ファイルで完結するスタンドアロンHTML版もあり、ブラウザで開くだけで使える。
デモページでそのまま使うか、Releases から wema.html をダウンロードしてブラウザで開く。
- 付箋の追加・編集・ドラッグ移動・リサイズ・削除
- 接続線(Edge)の作成・スタイル編集
- 接続線を空白にドロップ → そこに新しい付箋を自動作成して接続
- 部分木の折り畳み → 付箋にカーソルを乗せると折り畳みボタン(−)が出現。クリックで全ての接続先とその子孫を一括非表示。数字バッジをクリックで再展開
- リッチテキスト(太字、テキスト色、箇条書き、チェックボックス、リンク、画像、Embed)
- 複数選択・整列・均等配置・自動レイアウト
- Undo/Redo(Ctrl+Z / Ctrl+Y)
- autoSize モード(コンテンツに合わせて付箋サイズを自動調整)
- 5色のカラーパレット
- IndexedDB による自動保存
- JSON エクスポート/インポート
npm install @kanf/wemaimport { WemaBoard } from '@kanf/wema';
import '@kanf/wema/style.css';
const board = new WemaBoard({
container: document.getElementById('board'),
});
// 付箋を追加
const note = board.addNote({ x: 100, y: 80, text: 'Hello!' });
// 接続線を追加
const note2 = board.addNote({ x: 400, y: 80, text: 'World!' });
board.addEdge(note.id, note2.id);
// データをエクスポート
const data = board.exportData();
// イベントを購読
board.on('change', ({ data }) => {
console.log('Board changed:', data);
});const board = new WemaBoard({
container: HTMLElement, // マウント先
data?: WemaBoardData, // 初期データ
defaultNoteWidth?: number, // default: 200
defaultNoteHeight?: number, // default: 150
defaultNoteColor?: string, // default: '#FFF9C4'
createOnDblClick?: boolean, // default: true
readOnly?: boolean, // default: false
viewOnly?: boolean, // default: false
theme?: NoteTheme, // default: 'default' ('default' | 'card')
});| メソッド | 説明 |
|---|---|
addNote(params?) |
付箋を追加 |
updateNote(id, params) |
付箋を更新 |
deleteNote(id) |
付箋を削除 |
getNote(id) |
IDで取得 |
getNotes() |
全付箋を取得 |
| メソッド | 説明 |
|---|---|
addEdge(from, to, params?) |
接続線を追加 |
updateEdge(id, params) |
接続線を更新(線種・矢印・太さ・折り畳み等) |
deleteEdge(id) |
接続線を削除 |
getEdges() |
全接続線を取得 |
getEdgesOf(noteId) |
指定付箋に接続された線を取得 |
getSelectedEdge() |
選択中の接続線IDを取得 |
| メソッド | 説明 |
|---|---|
select(noteIds) |
付箋を選択 |
selectAll() |
全選択 |
getSelection() |
選択中のIDを取得 |
| メソッド | 説明 |
|---|---|
alignNotes(noteIds, alignment) |
付箋を整列(left/center/right/top/middle/bottom) |
distributeNotes(noteIds, direction) |
付箋を均等配置(horizontal/vertical) |
autoLayout(noteIds?) |
自動レイアウト(BFS階層) |
| メソッド | 説明 |
|---|---|
undo() |
元に戻す |
redo() |
やり直す |
canUndo() |
undo可能か |
canRedo() |
redo可能か |
| メソッド | 説明 |
|---|---|
setReadOnly(readOnly) |
読み取り専用モードを設定 |
isReadOnly() |
読み取り専用か |
setViewOnly(viewOnly) |
閲覧専用モードを設定(UIも非表示) |
isViewOnly() |
閲覧専用か |
setTheme(theme) |
テーマを設定('default' / 'card') |
getTheme() |
現在のテーマを取得 |
| メソッド | 説明 |
|---|---|
exportData() |
ボードデータをオブジェクトで返す |
importData(data) |
データを読み込み(現在の内容を置換) |
| イベント | ペイロード |
|---|---|
note:create |
{ note } |
note:update |
{ note, prev } |
note:delete |
{ note } |
note:select |
{ noteIds } |
edge:create |
{ edge } |
edge:update |
{ edge, prev } |
edge:delete |
{ edge } |
readOnly:change |
{ readOnly } |
viewOnly:change |
{ viewOnly } |
history:change |
{ canUndo, canRedo } |
change |
{ data } |
board.on('change', ({ data }) => { /* ... */ });
board.off('change', handler);付箋の作成・編集・移動・削除、接続線の操作をすべて禁止する。付箋の閲覧と選択は可能。
const board = new WemaBoard({ container, readOnly: true });
// または実行時に切り替え
board.setReadOnly(true);
board.setReadOnly(false);スタンドアロン版では 🔒 ボタン(Ctrl+L)で切替。状態はリロード後も保持される。
アンカー・リサイズハンドル・ポップアップなど編集 UI をすべて非表示にする。ロックモードより表示がクリーンで、ボードを「見せる」用途に向く。
const board = new WemaBoard({ container, viewOnly: true });
// または実行時に切り替え
board.setViewOnly(true);
board.setViewOnly(false);参照モード中も可能な操作(一時的・データは変更されない):
- 付箋のドラッグ移動 — モード終了時に元の位置に戻る
- 部分木の折り畳み/展開 — モード終了時に元の状態に戻る
スタンドアロン版では 👁 ボタン(Ctrl+Shift+L)で切替。状態はリロード後も保持される。
| 操作 | 通常 | ロック | 参照 |
|---|---|---|---|
| 付箋の閲覧 | ✓ | ✓ | ✓ |
| 付箋の移動 | ✓ | ✗ | ✓(一時的) |
| 付箋の編集 | ✓ | ✗ | ✗ |
| 付箋の追加・削除 | ✓ | ✗ | ✗ |
| 接続線の操作 | ✓ | ✗ | ✗ |
| 折り畳み/展開 | ✓ | ✗ | ✓(一時的) |
| Undo/Redo | ✓ | ✗ | ✗ |
interface WemaNote {
id: string;
x: number; y: number;
width: number; height: number;
text: string; // HTML文字列
color: string;
zIndex: number;
autoSize?: boolean; // コンテンツに合わせてサイズ自動調整
}
interface WemaEdge {
id: string;
from: string; to: string;
fromAnchor: 'top' | 'right' | 'bottom' | 'left' | 'auto';
toAnchor: 'top' | 'right' | 'bottom' | 'left' | 'auto';
style: 'arrow' | 'line' | 'dashed';
lineStyle?: 'solid' | 'dashed' | 'dotted';
arrowHead?: 'none' | 'start' | 'end' | 'both';
strokeWidth?: number;
arrowSize?: number;
routing?: 'curve' | 'polyline';
label?: string;
collapsed?: boolean; // true のとき接続先の部分木を非表示
}CSS変数でスタイルを調整できる:
.wema-board {
--wema-note-border-radius: 4px;
--wema-note-shadow: 0 2px 8px rgba(0,0,0,0.15);
--wema-note-font-size: 14px;
--wema-note-color-text: #333;
--wema-anchor-size: 12px;
--wema-anchor-color: #4A90D9;
--wema-edge-color: #555;
--wema-edge-width: 2px;
}npm install # 依存インストール
npm run dev # 開発サーバー (HMR)
npm run build # ビルド (dist/)
npm test # テスト
npm run lint # 型チェック