Agent skill
electron-ui-patterns
ElectronデスクトップアプリケーションのUI実装パターンと設計知識。 BrowserWindow管理、ネイティブUI要素、フレームレスウィンドウを提供。 Anchors: • Electron API / 適用: BrowserWindow・Menu・Tray / 目的: ネイティブUI実装 • Don't Make Me Think / 適用: ウィンドウレイアウト / 目的: ユーザビリティ向上 • Electron Security / 適用: preload・contextIsolation / 目的: セキュアなUI実装 Trigger: Use when configuring BrowserWindow, implementing custom titlebars, designing native menus, developing system tray apps, or building frameless windows. BrowserWindow, Menu, Tray, frameless window, custom titlebar, native UI
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/other/electron-ui-patterns
SKILL.md
Electron UI Patterns
概要
ElectronデスクトップアプリケーションのUI実装パターンと設計知識を提供。 BrowserWindow管理、ネイティブUI要素の活用、フレームレスウィンドウの実装を支援する。
ワークフロー
Phase 1: UI要件の整理
目的: 実装対象のUI要素を特定
アクション:
- 実装対象を特定(BrowserWindow、メニュー、ダイアログ)
references/で対応するパターンを確認- プロジェクト要件に合致するパターンを選定
Phase 2: UI実装
目的: UIパターンに従って実装
アクション:
- 該当する
agents/のTask仕様書を参照 assets/frameless-window.tsなどテンプレートを活用- BrowserWindow設定、スタイリング、イベントハンドリングを実装
- ネイティブUI要素(メニュー、ダイアログ、トレイ)を統合
Phase 3: 検証と記録
目的: 動作検証と記録
アクション:
- ウィンドウ表示、メニュー動作をテスト
scripts/log_usage.mjsで記録
Task仕様ナビ
| Task | 起動タイミング | 入力 | 出力 |
|---|---|---|---|
| browserwindow-setup | BrowserWindow設定時 | プロジェクト要件 | 初期化コード・preload |
| custom-titlebar | カスタムタイトルバー実装時 | デザイン仕様 | フレームレス設定・CSS |
| native-menu | ネイティブメニュー実装時 | 機能要件 | メニュー構築コード |
| system-tray | システムトレイ設定時 | アイコン画像 | Tray設定コード |
詳細仕様: 各Taskの詳細は agents/ ディレクトリの対応ファイルを参照
ベストプラクティス
すべきこと
- コンテキスト分離: preload.jsでコンテキストを分離
- BrowserWindow最小化: 必要最小限の機能のみ有効化
- IPC通信: メインとレンダラーの分離
- ネイティブUI活用: プラットフォーム固有のMenu/Dialog/Tray
- 状態永続化: ウィンドウ位置・サイズを保存
避けるべきこと
- nodeIntegration有効化: セキュリティリスク
- enableRemoteModule使用: 直接APIアクセスは避ける
- synchronous IPC: 非同期通信を使用
- プラットフォーム差異無視: Windows/macOS/Linuxの違いを考慮
リソース参照
references/(詳細知識)
| リソース | パス | 用途 |
|---|---|---|
| ネイティブUI | See references/native-ui.md | メニュー・ダイアログ |
| ウィンドウ管理 | See references/window-management.md | BrowserWindow詳細 |
| エディタ統合 | See references/editor-integration.md | EditorInstance・検索統合 |
scripts/(決定論的処理)
| スクリプト | 用途 | 使用例 |
|---|---|---|
log_usage.mjs |
フィードバック記録 | node scripts/log_usage.mjs --result success --phase "Phase 3" |
validate-skill.mjs |
スキル構造検証 | node scripts/validate-skill.mjs --verbose |
assets/(テンプレート)
| テンプレート | 用途 |
|---|---|
frameless-window.ts |
フレームレスウィンドウテンプレート |
実装事例(2026-01-06追加)
EditorView検索統合リファクタリング
search-replace-ui-implementation Phase 10で、ElectronアプリのEditorViewコンポーネントに検索・置換機能を統合した事例。
背景と要件
デスクトップアプリのエディタビューに以下の検索機能を統合する必要があった:
- ファイル内検索・置換(Cmd+F / Cmd+T)
- ワークスペース全体検索・置換(Cmd+Shift+F / Cmd+Shift+T)
- ファイル名検索(Cmd+P)
課題として、検索機能はElectron IPC経由でメインプロセスと通信する必要があり、エディタ操作(ハイライト、スクロール、置換)とも連携が必要だった。
適用したパターン
EditorInstanceアダプターパターン
異なるエディタ実装(TextArea、Monaco Editor、CodeMirror)を統一APIで操作するためのアダプターパターンを適用。
-
EditorInstanceインターフェースを定義
- getContent(): エディタ内容を取得
- scrollToLine(line, column): 指定位置にスクロール
- replaceText(line, column, length, replacement): 単一箇所を置換
- replaceAllText(matches, replacement): 複数箇所を一括置換
- focus(): エディタにフォーカス
-
TextAreaEditorAdapterを実装
- HTMLTextAreaElementをEditorInstanceインターフェースでラップ
- 文字位置から行・列への変換ロジックを内包
- 将来Monaco Editorに移行時はMonacoEditorAdapterを実装するだけで対応可能
IPC検索プロバイダーパターン
Electron IPC通信をカプセル化し、検索パネルがIPC詳細を知らなくても検索を実行できるようにした。
- WorkspaceSearchProviderをAsyncGeneratorとして定義
- ファイル単位で検索結果をyieldし、UIが段階的に結果を表示可能
- EditorView側でuseWorkspaceSearchフックとして提供
- 検索パネルはプロバイダーを受け取るだけで、IPC通信の詳細は隠蔽
キーボードショートカット統合パターン
エディタと検索パネル間のキーボード操作を一元管理。
- useSearchKeyboardShortcutsフックでイベントハンドリングを集約
- 検索モード(file/workspace/filename)に応じた動作の切り替え
- パネル表示中はパネル内でのキー操作を優先(Escapeでパネル閉じる等)
Electron固有の考慮事項
-
IPC通信のオーバーヘッド
- 検索はメインプロセスで実行し、結果をレンダラーに返却
- 大量結果時はストリーミングで段階的に返却
-
コンテキスト分離
- preload.jsで公開するAPIを最小限に
- 検索APIはelectronAPI.search.executeWorkspaceとして公開
-
フォーカス管理
- 検索パネル表示時にフォーカスを検索入力に移動
- パネル閉じる時にエディタにフォーカスを戻す
成果
- EditorView: 713行 → 495行(約30%削減)
- 検索機能を独立したfeatureモジュール(apps/desktop/src/features/search/)として分離
- エディタ実装変更時の影響をアダプター層に局所化
- IPC通信のモック化によりテスト容易性向上
IPC通信エラーハンドリングパターン(2026-01-10追加)
CONV-05-03(履歴/ログ表示UIコンポーネント)で適用したIPC通信のエラーハンドリングパターン。
パターン概要
Electron IPC通信において、以下のエラー状況に対応するための統一的なパターン。
| エラー種別 | 原因 | 対応 |
|---|---|---|
| API未利用可能 | preload未設定、contextBridge未公開 | 明示的なエラーメッセージ |
| IPC通信失敗 | チャンネル未登録、タイムアウト | 再試行機能付きエラー表示 |
| データ取得失敗 | DBエラー、ファイル不在 | Result型でエラー情報を伝播 |
Result型パターン
IPC通信の結果を型安全に扱うためのパターン。
// 成功/失敗を型で区別
interface SuccessResult<T> {
success: true;
data: T;
}
interface ErrorResult {
success: false;
error: Error;
}
type Result<T> = SuccessResult<T> | ErrorResult;
// 使用例:IPC応答の処理
const result = await window.historyAPI.getFileHistory(fileId, options);
if (result.success) {
setHistory(result.data.items);
} else {
setError(result.error);
}
API利用可能性チェックパターン
preloadスクリプトでAPIが正しく公開されているかを確認。
function useVersionHistory(fileId: string) {
const [error, setError] = useState<Error | null>(null);
const fetchHistory = useCallback(async () => {
// API利用可能性チェック
if (!window.historyAPI) {
setError(new Error("History API not available"));
setIsLoading(false);
return;
}
try {
const result = await window.historyAPI.getFileHistory(fileId);
// ...
} catch (err) {
setError(err instanceof Error ? err : new Error(String(err)));
}
}, [fileId]);
}
再試行機能付きエラー表示パターン
エラー発生時にユーザーが再試行できるUIを提供。
function ErrorDisplay({
message,
onRetry,
}: {
message: string;
onRetry: () => void;
}) {
return (
<div role="alert" className="rounded-lg bg-red-50 p-4 text-center">
<p className="mb-3 text-red-700">エラーが発生しました: {message}</p>
<button
type="button"
onClick={onRetry}
className="rounded-lg bg-red-600 px-4 py-2 text-sm font-medium text-white"
>
再試行
</button>
</div>
);
}
// 使用例:履歴一覧でのエラーハンドリング
if (error && history.length === 0) {
return <ErrorDisplay message={error.message} onRetry={refresh} />;
}
Window型拡張パターン
TypeScriptでwindowオブジェクトの拡張を型安全に行う。
// types.tsで型を定義
interface HistoryAPI {
getFileHistory(
fileId: string,
options?: PaginationOptions,
): Promise<Result<PaginatedResult>>;
// ...
}
declare global {
interface Window {
historyAPI?: HistoryAPI; // ?でオプショナルに
}
}
// コンポーネントでの使用
if (window.historyAPI) {
const result = await window.historyAPI.getFileHistory(fileId);
}
エラー種別の分類
| エラークラス | 表示メッセージ | 再試行 |
|---|---|---|
| NetworkError | 「通信エラーが発生しました」 | 可 |
| NotFoundError | 「データが見つかりません」 | 不可 |
| RestoreError | 「復元に失敗しました」 | 可 |
| DBError | 「データベースエラーが発生しました」 | 可 |
実装詳細
詳細は以下を参照:
- 実装例:
apps/desktop/src/renderer/hooks/useVersionHistory.ts - 型定義:
apps/desktop/src/renderer/components/history/types.ts - 仕様書:
.claude/skills/aiworkflow-requirements/references/ui-ux-history-panel.md
変更履歴
| Version | Date | Changes |
|---|---|---|
| 2.4.0 | 2026-01-10 | IPC通信エラーハンドリングパターン追加(CONV-05-03) |
| 2.3.0 | 2026-01-06 | validate-skill.mjs追加 |
| 2.2.0 | 2026-01-06 | editor-integration.md追加、skill-creator準拠 |
| 2.1.0 | 2026-01-06 | EditorView検索統合パターン追加 |
| 2.0.0 | 2026-01-01 | 18-skills.md仕様完全準拠、構造最適化 |
| 1.0.0 | 2025-12-31 | 初版作成 |
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?