Component 15 of 60
Context Menu
A menu opened by a secondary pointer action.
Starting the preview. GPUI compiles to WebAssembly, so the first load takes a few seconds. This browser has neither WebGPU nor WebGL 2, so the live preview cannot run. The code on this page still works. The preview did not start.
fn context_menu_preview(&self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let click = cx.listener(|this, _, _, cx| {
this.demo_action = "Copied".into();
cx.notify();
});
let menu = window.use_keyed_state("context-menu", cx, |_, cx| {
MenuState::new(
[
MenuItem::new("copy", "Copy").on_click(click),
MenuItem::new("paste", "Paste").disabled(true),
MenuItem::separator(),
MenuItem::new("show-bookmarks", "Show bookmarks").checked(true),
MenuItem::submenu(
"share",
"Share",
[MenuItem::new("documentation", "Documentation")
.link()
.on_click(|_, _, cx| cx.open_url("https://ui.imajha.com"))],
),
],
cx,
)
});
gpuicn::context_menu::context_menu(
&menu,
"File actions",
div()
.w(px(280.))
.h(px(160.))
.border_1()
.border_color(UiTheme::read(cx).colors.border)
.rounded(px(8.))
.flex()
.items_center()
.justify_center()
.child("Right click here"),
)
}
Installation
After the one-time setup, run the command from your app root. The CLI
writes the modules and keeps src/ui/mod.rs in step.
gpuicn add context-menu
If you prefer to copy the files by hand, declare them yourself:
// src/ui/mod.rs
pub mod theme;
pub mod button;
pub mod menu;
pub mod context_menu;
// src/main.rs
mod ui;
Usage
Put this in a view module and return example(state) from its render method.
use crate::ui::context_menu::*;
use crate::ui::menu::*;
use gpui_kit::{Entity, IntoElement, ParentElement};
fn example(state: &Entity<MenuState>) -> impl IntoElement {
context_menu(
state,
"File actions",
gpui_kit::div().child("Right-click here"),
)
}
API reference
pub fn context_menu(
state: &Entity<MenuState>,
label: impl Into<SharedString>,
area: impl IntoElement,
) -> Menu
Attach a context menu to a focusable area. The caller owns its menu state.
Installed source, 12 lines
//! Right-click and Shift-F10 menus using the shared Nova menu state.
use super::menu::{Menu, MenuState};
use gpui_kit::{Entity, IntoElement, SharedString};
/// Attach a context menu to a focusable area. The caller owns its menu state.
pub fn context_menu(
state: &Entity<MenuState>,
label: impl Into<SharedString>,
area: impl IntoElement,
) -> Menu {
Menu::new(state, label).context_area(area)
}
Platform notes
Visual reference: shadcn/ui 4.19.0, Neutral Nova. Implementation:
crates/ui/registry/context_menu/context_menu.rs, using GPUI Kit 0.6.4.
MenuState owns the popup, highlighted item and submenu path. Secondary click or Shift+F10 opens the menu; arrows, Home, End, typeahead, Enter and Escape navigate it. Primary clicks remain available to the wrapped content, including Virtual List selection.
The Rust source and Usage example define the supported API. Browser DOM/CSS behavior, exact exit animations and cross-platform screen-reader parity are not implied by the native component. See migration qualification for the checks completed on this revision.