command-dock
v0.2.0
Published
Framework-agnostic bottom-center command dock Web Component (circular triggers + popovers, single-open / click-outside behavior, CSS-variable theming).
Maintainers
Readme
command-dock
下部中央に並ぶ円形トリガーと、その上に出るポップオーバーを提供する、フレームワーク非依存の
Web Component(カスタム要素 <command-dock>)。開閉(単一オープン)・外クリックで閉じる・項目
選択で自動クローズ、の挙動を内蔵する。中身は items プロパティで宣言的に注入する。
vanilla / React / Vue いずれからも <command-dock> を置くだけで使える。スタイルは Shadow DOM に
閉じ込め、テーマは CSS 変数で受ける(--dock-* を最優先、無ければホストアプリの汎用変数へ
フォールバック)。
インストール
// git 依存(リポジトリを push 後)
"dependencies": { "command-dock": "github:yanqirenshi/command-dock#v0.1.0" }
// ローカル開発時
"dependencies": { "command-dock": "file:../command-dock" }トリガーの2種類
各円形トリガーは DockItem で定義し、持たせるキーで挙動が決まる(判別ユニオン)。
| 種類 | 判別キー | クリック時の挙動 |
|---|---|---|
| 吹き出し型 | popup | ポップオーバーを開く(単一オープン・外クリックで閉じる) |
| 即アクション型 | onClick | onClick を即実行(吹き出しは出さない) |
即アクション型の onClick が Promise を返すと、その解決(または reject)まで自動で
disabled + スピナー(busy) 表示になり、二重実行を防ぐ。外部状態で無効化したいときは
disabled(真偽値 or 述語)を使い、refresh() で再評価する。
使い方
import "command-dock"; // 副作用 import: <command-dock> を登録する(必須)
import type { DockItem } from "command-dock";
const dock = document.querySelector("command-dock")!;
dock.items = [
{
// 即アクション型: クリックで即実行。Promise を返すと解決まで disabled + busy。
id: "refresh",
label: "R",
title: "再読み込み (R)",
onClick: async () => {
await fetchData();
rerender();
},
},
{
// 吹き出し型(フラットな項目配列)
id: "file",
label: "F",
title: "ファイル操作 (F)",
popup: [
{ icon: "<svg…>", label: "新規作成", onSelect: () => handleNew() },
{ icon: "<svg…>", label: "開く", onSelect: () => handleOpen() },
],
},
{
// 吹き出し型(見出し付きグループ + active 述語)
id: "view",
label: "V",
title: "表示設定 (V)",
popup: {
section: "表示モード",
items: [
{ label: "エディタ", active: () => mode === "editor", onSelect: () => setMode("editor") },
{ label: "分割", active: () => mode === "split", onSelect: () => setMode("split") },
],
},
},
];
// 外部状態が変わったら、開いている popup の active 表示と
// 即アクション型の disabled 述語を再評価する
dock.refresh();重要: 登録は必ず
import "command-dock";(副作用 import)で行う。型としてしか使わないと 本番ビルドの tree-shake でcustomElements.defineが落ち、要素が登録されない。本パッケージはpackage.jsonのsideEffectsで保護しているが、利用側でも副作用 import を徹底すること。
API
<command-dock> 要素(CommandDock):
- プロパティ
items: DockItem[]— 代入で再描画 - メソッド
open(id)(吹き出し型のみ)/closeAll()/refresh() - イベント
select(吹き出し項目の選択時。detail: { dockId, index, label }) - イベント
action(即アクション型のクリック時。detail: { dockId, label })
いずれのイベントも bubbles + composed(Shadow DOM を貫通)。
配置は既定で下部中央(:host { position:absolute; bottom:28px; left:50% })。包含ブロックを持つ
親(position: relative など)の中に置くと、その親基準で配置される。
テーマ契約(CSS 変数)
| 変数 | フォールバック | 用途 |
|---|---|---|
| --dock-bg | --bg-secondary | ボタン/ポップオーバー背景 |
| --dock-fg | --text-primary | 文字色 |
| --dock-border | --border-color | 枠線 |
| --dock-accent | --accent-color | hover/active のアクセント |
| --dock-accent-bg | --dock-accent | active ボタンの塗り |
| --dock-accent-fg | #fff | active ボタンの文字 |
| --dock-glow | 青系 | active ボタンの影色 |
| --dock-bg-hover / --dock-active-bg / --dock-muted / --dock-shadow | 各汎用変数 | hover背景 / 選択中背景 / 見出し / 影 |
| --dock-bottom / --dock-gap / --dock-z | 28px / 16px / 100 | 位置・間隔・重なり |
CSS 変数は Shadow DOM を貫通するので、ホスト側でテーマクラスに --dock-* を定義すれば上書きできる。
ビルド
npm install
npm run build # tsc が dist/ に ESM + 型定義を出力git 依存でインストールされる際は prepare スクリプトで自動ビルドされる。
