mcpField
S
scene-menu-bar

scene-menu-bar

github.com/posthogデザイン・UI40.5k141 回インストール今日更新
リポジトリ

scene-menu-bar について

PostHog のシーンメニューバーを設計・移行するための開発スキルです。メニュー構成、コンポーネントの使い方、操作ルール、移行時の確認事項をまとめています。

主な機能

  1. 01File、Edit、View、Metadata のメニュー規則
  2. 02破壊的操作と切り替え項目の指針
  3. 03リッチなフォーム入力向けポップオーバー
  4. 04キーボード操作とレイアウトの指針
  5. 05移行とシーン監査のチェックリスト

活用シーン

  1. 01ScenePanel のメニューバーへの移行
  2. 02シーン操作のメニュー分類
  3. 03タグなどのリッチ入力の追加
  4. 04メニューの操作性とアクセシビリティの確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/posthog/posthog --skill scene-menu-bar

インストール後、Claude Code で/scene-menu-barを入力して読み込まれたか確認します。

詳細

SceneMenuBar の規約

PostHog のシーンは <SceneTitleSection> の上に Mac 風のメニューバーをレンダリングし、ScenePanel のアクションを発見しやすくキーボードで操作可能なサーフェスに集約します。このスキルでは、分類体系、利用可能なプリミティブ、および配線ルールについて説明します。

バー全体は SCENE_MENU_BAR 機能フラグによって制御されます(lib/constants.tsx を参照)。

コンポーネント

すべてのプリミティブは frontend/src/layout/scenes/components/SceneMenuBar.tsx にあります。

コンポーネント用途
<SceneMenuBar>トップレベルのラッパー。<SceneTitleSection> の上にレンダリングされます。共通の右側クラスター(PostHog AI / Docs / Support)を含みます。
<SceneMenuBarMenu label>トップレベルメニュー(File / Edit / View / Metadata / Staff のみ)。
<SceneMenuBarSubMenu label>SceneMenuBarMenu 内のネストされたサブメニュー(例: Create、Export、Add to notebook)。トリガーに空のアイコンスロットを自動的に先頭追加し、ラベルがアイコン付きの兄弟要素と揃うようにします — オプトアウトするには withIconBlank={false} を渡します。
<SceneMenuBarItem>標準のメニュー項目(アクション / ナビゲーション)。
<SceneMenuBarCheckboxItem>トグル項目 — チェックマークで真偽状態を反映します。
<SceneMenuBarRadioGroup> + <SceneMenuBarRadioItem>多数の中から 1 つを選ぶ排他的なオプション。
<SceneMenuBarSeparator>グループ間の水平方向の区切り線。
<SceneMenuBarShortcut>右揃えのキーボードショートカットのヒント。
<SceneMenuBarPopover label>コンテンツにリッチなフォームコントロール(テキスト入力、コンボボックス)が必要な場合に SceneMenuBarMenu の代わりにそのまま使える選択肢。内部的に Popover を使用します — Menu.Popup はキーストロークを横取りして入力をブロックします。トリガーは CompositeRoot のキーボードナビゲーションに参加しません。

正規のメニューセット(順序どおり)

メニュー項目
File+ Create サブメニュー(先頭)、── 、プロジェクトツリー項目(Open / Move / Star)、別のプロジェクトへコピー、Terraform で管理、シーン固有のファイル操作、Export サブメニュー、──、Delete / Archive / Restore(破壊的項目は最下部)
EditDuplicate、Rename、SQL エディターで編集、シーン固有の編集、状態変更(Pause/Resume、Activate/Deactivate)、──、トグルグループ(チェックボックス/ラジオ項目。通常項目とは <SceneMenuBarSeparator> で区切る)
View (条件付き)クロスリソース表示 — View recordings、View metalytics、View related insights など。現在のリソースに間接的に関連するものを 見る ためにナビゲートするものはすべてここに含めます。空の場合はスキップします。
Metadata (SceneMenuBarPopover を使用)Tags、Evaluation contexts、Stage、Activity indicator、External references、Comments など。
Staff only (条件付き)デバッグパネル、スタッフ専用トグル。スタッフ / superpowers / なりすまし中 / 非クラウドユーザーにのみレンダリングします。

状態は Edit にあります。 Pause/Resume、Activate/Deactivate、Favorite/Pin トグルなどの 状態変更はすべて Edit メニューの内部にあります — 通常は最下部で、トグルグループがある場合は <SceneMenuBarSeparator> の後ろです。独立した State メニューを作成しないでください。

右側のクラスターは固定で共通です: PostHog AI · Docs · Support。ここには何も追加しないでください。

ルール

破壊的なアクション(Delete / Archive / Restore)
  • File の最下部に配置し、上にあるファイル操作とは <SceneMenuBarSeparator> で区切ります。
  • 視覚的な表現のために variant="destructive" を渡します(赤いテキスト + アイコン)。
  • 確認ダイアログを開く場合でも、破壊的な項目には opensFloatingUi を 追加しないでください — 破壊的バリアントと明確なラベルで十分なシグナルになります。
  • リソースにアクセス制御レベルがある場合は <AccessControlAction> でラップします。
トグルグループ
  • すべての <SceneMenuBarCheckboxItem> と <SceneMenuBarRadioGroup> 項目をまとめてグループ化します。
  • 通常のアクション項目とは <SceneMenuBarSeparator> で区切ります(上に、そしてさらに項目が続く場合は下にも)。
  • 安定したラベルを使用します — チェックマークが状態を伝えます: Pin/Unpin ではなく Pinned、Show/Hide debug panel ではなく Show debug panel。
  • 相互排他的な選択肢にはラジオを使用します(<SceneMenuBarRadioGroup value onValueChange>)。
opensFloatingUi プロップ

追加のフローティング UI を開く項目には、Mac スタイルのアフォーダンスとして項目ラベルの末尾に … を追加します:

  • ✅ 使用する: モーダル、ポップオーバー、ダイアログ、サイドパネルのオープナー
  • ❌ スキップする: 同一ページ内ナビゲーション、直接アクション、破壊的な項目(破壊的なスタイルがすでに結果を示しています)、トグル項目
+ Create クロスセル
  • File の先頭にある <SceneMenuBarSubMenu label="Create"> の中にネストします。
  • Create と File の残りの間に <SceneMenuBarSeparator> を配置します。
  • クロスセル: Cohort、Survey、Dashboard、Notebook、Endpoint、Subscription、Alert、Share or embed。
空のメニュー

SceneMenuBarMenu は、コンパイル時に子要素が何もレンダリングしない場合(例:{false && <Item/>}、{null}、空のフラグメント)、トリガーを自動的に無効にします。トリガーは表示されたまま(グレー表示で、cursor-not-allowed)になるため、メニューセットを通じてユーザーにバーの機能を伝えられます。

子要素が実行時に null をレンダリングする可能性があるメニュー(最も一般的な例は <SceneMenuBarFileItems> です。プロジェクトツリーのエントリが登録されていない場合、または Today レイアウトが有効な場合に sceneFileLogic.hasFileItems が false となり、null を返します)では、親はポップアップが空になることを検知できません。次のいずれかを行ってください。

  1. 子要素が依存する値と同じ値に基づいて、disabled を明示的に渡します。例:

    const { hasFileItems } = useValues(sceneFileLogic)
    <SceneMenuBarMenu label="File" disabled={!hasFileItems}>
        {hasFileItems && <SceneMenuBarFileItems dataAttrKey="…" />}
    </SceneMenuBarMenu>
    
  2. 有用なものを何もレンダリングできない場合は、親でメニュー全体の表示を制御します。

    {
      hasAnyEditItem && <SceneMenuBarMenu label="Edit">…</SceneMenuBarMenu>
    }
    

メニューの存在がシーンのアイデンティティの一部である場合(無効でも File は常に表示するなど)は(1)を優先し、メニューが本当に任意の場合(View、Staff のみなど)は(2)を優先してください。

タグ/評価コンテキスト/その他のリッチ入力
  • <SceneMenuBarMenu> ではなく、<SceneMenuBarPopover> の内側に配置する必要があります。メニューのポップアップはキーストロークを横取り(タイプアヘッド、矢印キーによる移動)し、テキスト入力が入力を受け取れないようにします。
  • 複数選択のチップ入力には <TagsCombobox>(lib/components/Scenes/TagsCombobox.tsx)を使用します。デフォルトでは選択のみ可能です。末尾に「新しい {noun} '...' を作成」という項目を表示するには、allowCustomValues を渡します。
  • <SceneTagsCombobox>(lib/components/Scenes/SceneTagsCombobox.tsx)は、SCENE_MENU_BAR のときに <SceneTags> と置き換えて使える、すぐに利用可能なラッパーです。
デバウンスを使った楽観的な保存

メニューバーの入力(タグ、切り替え)を自動保存する場合は、次の処理を行う kea リスナーを使用します。

  1. API 呼び出しの前に、setX と updateX で楽観的に更新します。
  2. 連続した変更をデバウンスするため、await breakpoint(250) を実行します。
  3. より新しい呼び出しによって古くなった処理を中断できるよう、API 応答の後に breakpoint() を実行します。
  4. サーバーから返された値の順序が異なる場合に並べ替えが発生しないよう、反映する前に集合の等価性を確認します。
  5. error.isBreakpoint を再スローして、kea がエラーを通知せずに処理できるようにします。

frontend/src/scenes/feature-flags/featureFlagLogic.ts の saveTagsInline を参照してください。

File メニュー — プロジェクトツリーの項目

File の末尾(破壊的操作の区切り線の前)に <SceneMenuBarFileItems dataAttrKey={RESOURCE_TYPE} /> を使用すると、プロジェクトツリーで開く、フォルダーに移動、スターに追加/スターから削除を表示できます。sceneFileLogic.hasFileItems が false の場合は自動的に非表示になります。

右側のクラスター

実際のメニューで CompositeRoot のキーボードナビゲーションを機能させるため、<Menubar> ラッパーの外側に配置します。UX レビューなしにここへ項目を追加しないでください。

レイアウトに応じたはみ出し

<SceneMenuBar> は sceneLayoutLogic.sceneLayoutConfig.layout を読み取り、レイアウトにパディングがある場合にのみシーンコンテナーのパディングを越えてはみ出します(-mx-4 -mt-4)。対象となるのは app、app-container、app-full-scene-height です。パディングのないレイアウト(app-raw、app-raw-no-header、plain)では、負の値を設定すると必要以上にはみ出し、ヘッダーの見た目が崩れるため適用されません。シーン側で特別な対応は不要です。適切な SceneConfig.layout を登録するだけで、バーが自動的に調整されます。デバッグ用に、ラッパーには data-scene-layout 属性が設定されます。

移行済みのシーン

  • Feature Flag — frontend/src/scenes/feature-flags/FeatureFlag.tsx
  • Insight — products/product_analytics/frontend/insights/insightScene/sidePanel/InsightSceneMenuBar.tsx
  • Dashboard — frontend/src/scenes/dashboard/DashboardSceneMenuBar.tsx

新しいシーンを移行する際は、<Scene>SceneMenuBar.tsx のパターンに従ってください(featureFlagLogic を読み込み、フラグがオフなら早期に null を返し、オンならバーをレンダリングするコンポーネント)。<SceneTitleSection> のすぐ上に直接マウントしてください。

シーンの監査

シーンを移行する際は、既存の ScenePanel を取得し、すべての項目を次のようにマッピングします。

  1. どのメニューに属するか(File / Edit / View / Metadata / Staff only)。
  2. variant="destructive" が必要かどうか(delete/archive/remove)。
  3. opensFloatingUi が必要かどうか(モーダル/ポップオーバー/ダイアログ/サイドパネルを開く)。
  4. トグルかどうか(SceneMenuBarCheckboxItem を使用)。
  5. どのようなゲートが適用されるか(保存状態、FF、AccessControl、マルチプロジェクト)。

PostHog 全体にわたるすべての ScenePanel 項目と、それらに対して提案されたメニュー配置の最新の一覧については、/Users/adamleithp/Desktop/scene-menu-bar-grouping.md を参照してください。

コメント