Components

Context Menu

Displays a menu of actions triggered by a right click.

Overview

在虚线框里右键 —— 菜单在指针处弹出,点击外部或 Escape 关闭。

GPUI · Live previewGPUI WASM

Installation

Context Menu 是单个 Rust 文件(src/context_menu.rs)—— 浮层走 deferred() overlay pass,键盘导航用 FocusHandle + on_key_down,图标和 ⌘/⇧/⌥/⌃ 修饰键全部 PathBuilder 手绘(Geist 没有这些码位)。

Cargo.toml
[dependencies]gpui-kit = "0.6.6"# context_menu.rs is self-contained: FocusHandle for keyboard# nav, deferred() for the popup pass, PathBuilder glyphs — no# extra deps.

Download runnable example

Terminal
# Download the runnable example crate, then:cargo run --locked -- --context-menu# Other demos:cargo run --locked -- --context-menu submenucargo run --locked -- --context-menu selectioncargo run --locked -- --context-menu destructive

Usage

ContextMenu 是实体:.trigger(..) 接收一个元素工厂作为右键区域,菜单项用 ContextMenuEntry 枚举声明(Item / Label / Separator)。右键在指针处弹出,点击行发出 ContextMenuSelectEvent。

Example.rs
use justdo_command::context_menu::{    ContextMenu, ContextMenuEntry, ContextMenuItem, ContextMenuSelectEvent,};let menu = cx.new(|cx| {    ContextMenu::new(        // Trigger area — any renderable element factory.        move || {            div()                .p_4()                .border_1()                .border_dashed()                .child("Right click here")                .into_any_element()        },        vec![            ContextMenuEntry::Item(ContextMenuItem::new("Profile")),            ContextMenuEntry::Item(ContextMenuItem::new("Billing")),            ContextMenuEntry::Item(                ContextMenuItem::new("Settings").shortcut("⌘S"),            ),            ContextMenuEntry::Separator,            ContextMenuEntry::Item(                ContextMenuItem::new("Delete").destructive(true),            ),        ],        cx,    )});cx.subscribe(&menu, |view, _, ev: &ContextMenuSelectEvent, cx| {    view.handle(ev.value.clone());    cx.notify();});div().size_full().child(menu)

网页预览与桌面端运行同一份 Rust / GPUI 组件。

Composition

结构对应 ContextMenuTrigger + ContextMenuContent → Item / Label / Separator / Sub / CheckboxItem / RadioItem / Shortcut。子菜单用 .submenu(vec![...]) 内嵌,复选与单选行提交后菜单保持打开。

Structure
ContextMenu                entity — trigger + popup + nav state├── ContextMenuTrigger    .trigger(factory) — right-click surface│                         (secondary-button MouseDown → open at pointer)├── ContextMenuContent    floating panel — deferred pass, viewport-clamped│   ├── ContextMenuGroup  ContextMenuEntry::Label — muted heading│   ├── ContextMenuItem   icon + label + shortcut + ▸│   │                     .value(..) .icon(..) .shortcut(..)│   │                     .disabled(..) .destructive(..)│   ├── ContextMenuCheckboxItem   .checkbox(bool) — stays open on toggle│   ├── ContextMenuRadioItem      .radio("group") — exclusive per group│   ├── ContextMenuSeparator      ContextMenuEntry::Separator│   └── ContextMenuSub    ContextMenuItem::submenu(vec![...])│         └── SubContent  second panel at the trigger row└── emits                 ContextMenuSelectEvent { value, checked, group }
Positioning.rs
// Pointer coordinates arrive in window space; the component// captures its root bounds each prepaint and converts to local// space, so the menu anchors correctly wherever the trigger// sits. Panels clamp inside the root bounds (MENU_W = 208px).//// Right-clicking elsewhere while open re-anchors the menu —// same as the OS menu.

Keyboard

菜单打开时焦点移到浮层:↑/↓ 移动高亮(跳过禁用行),→ 打开子菜单,← 收起子菜单,Enter 执行,Escape 关闭。鼠标 hover 同样驱动高亮与子菜单开合。

Key handling.rs
// When the menu opens, a FocusHandle on the overlay takes// keyboard focus:////   ↑ / ↓    move the active row (disabled rows are skipped)//   →        open the submenu under the active row//   ←        close the submenu (or the menu)//   Enter    activate the active row//   Escape   close//// Hovering a row also moves the highlight and opens its// submenu, mirroring OS menus.

Accessibility

Semantics

禁用行半透明且不进入高亮序列;destructive 项红色双重标识;checkbox 行渲染 ✓、radio 行渲染圆点,状态可从实体读取(checked(..) / radio_value(..))。

Dismissal

点击外部 / Escape / 选择普通项关闭;右键点击别处把菜单重新锚定到新的指针位置,与系统菜单一致。

API Reference

实体暴露的构造器、builder 方法与事件。

APISignatureNotes
ContextMenu::new(..)trigger factory, Vec<ContextMenuEntry>Trigger renders via a factory closure.
ContextMenuItem::new(..)&str label.value(..) .icon(..) .shortcut(..) .disabled(..) .destructive(..)
.checkbox(..)boolToggle row; menu stays open.
.radio(..)&str groupExclusive within the group.
.submenu(..)Vec<ContextMenuEntry>Nested panel (one level deep).
.set_open(..)bool, Window, cxControlled open at trigger center.
.checked(..)-> Option<bool>Checkbox state by value.
.radio_value(..)-> Option<SharedString>Current value of a radio group.
ContextMenuSelectEvent{ value, checked, group }Emitted on every activation.

Source & inspiration

结构与交互参考 shadcn/ui Context Menu (React Aria) 。本页交互由 Rust / GPUI 绘制,基础原语来自 gpui-kit 。