Context Menu
Displays a menu to the user — such as a set of actions or functions — triggered by right click or long press.
This component uses newly available browser features
This component uses CSS Anchor Positioning which has only been widely supported since January 2026. If you're targeting older or less mainstream browsers then maybe this component isn't for you, yet.
Alternatively you can use Singlestage 0.4 which positions the component correctly but with limited flexibility for alignment, or roll your own using Singlestage CSS classes for consistent styling.
More Infouse leptos::prelude::*; use singlestage::*; #[component] pub fn ContextMenuExample() -> impl IntoView { view! { <ContextMenu> <ContextMenuTrigger class="flex h-[150px] w-[300px] items-center justify-center rounded-xl border border-dashed text-sm"> <span class="pointer-fine:hidden">"Long press here"</span> <span class="pointer-coarse:hidden">"Right click here"</span> </ContextMenuTrigger> <ContextMenuContent class="w-48"> <ContextMenuGroup> <ContextMenuItem> "Back" <ContextMenuShortcut>"⌘["</ContextMenuShortcut> </ContextMenuItem> <ContextMenuItem disabled=true> "Forward" <ContextMenuShortcut>"⌘]"</ContextMenuShortcut> </ContextMenuItem> <ContextMenuItem> "Reload" <ContextMenuShortcut>"⌘R"</ContextMenuShortcut> </ContextMenuItem> <ContextMenuSub> <ContextMenuSubTrigger>"More Tools"</ContextMenuSubTrigger> <ContextMenuSubContent class="w-44"> <ContextMenuGroup> <ContextMenuItem>"Save Page..."</ContextMenuItem> <ContextMenuItem>"Create Shortcut..."</ContextMenuItem> <ContextMenuItem>"Name Window..."</ContextMenuItem> </ContextMenuGroup> <ContextMenuSeparator /> <ContextMenuGroup> <ContextMenuItem>"Developer Tools"</ContextMenuItem> </ContextMenuGroup> <ContextMenuSeparator /> <ContextMenuGroup> <ContextMenuItem variant="destructive">"Delete"</ContextMenuItem> </ContextMenuGroup> </ContextMenuSubContent> </ContextMenuSub> </ContextMenuGroup> <ContextMenuSeparator /> <ContextMenuGroup> <ContextMenuCheckboxItem checked=true>"Show Bookmarks"</ContextMenuCheckboxItem> <ContextMenuCheckboxItem>"Show Full URLs"</ContextMenuCheckboxItem> </ContextMenuGroup> <ContextMenuSeparator /> <ContextMenuGroup> <ContextMenuRadioGroup value="pedro"> <ContextMenuLabel>"People"</ContextMenuLabel> <ContextMenuRadioItem value="pedro">"Pedro Duarte"</ContextMenuRadioItem> <ContextMenuRadioItem value="colm">"Colm Tuite"</ContextMenuRadioItem> </ContextMenuRadioGroup> </ContextMenuGroup> </ContextMenuContent> </ContextMenu> } }
Basic
A simple context menu with a few actions.
use leptos::prelude::*; use singlestage::*; #[component] pub fn ContextBasicExample() -> impl IntoView { view! { <ContextMenu> <ContextMenuTrigger class="flex h-[150px] w-[300px] items-center justify-center rounded-xl border border-dashed text-sm"> <span class="pointer-fine:hidden">"Long press here"</span> <span class="pointer-coarse:hidden">"Right click here"</span> </ContextMenuTrigger> <ContextMenuContent> <ContextMenuGroup> <ContextMenuItem>"Back"</ContextMenuItem> <ContextMenuItem disabled=true>"Forward"</ContextMenuItem> <ContextMenuItem>"Reload"</ContextMenuItem> </ContextMenuGroup> </ContextMenuContent> </ContextMenu> } }
Submenu
Use MenuSub to nest secondary actions.
use leptos::prelude::*; use singlestage::*; #[component] pub fn ContextSubExample() -> impl IntoView { view! { <ContextMenu> <ContextMenuTrigger class="flex h-[150px] w-[300px] items-center justify-center rounded-xl border border-dashed text-sm"> <span class="pointer-fine:hidden">"Long press here"</span> <span class="pointer-coarse:hidden">"Right click here"</span> </ContextMenuTrigger> <ContextMenuContent> <ContextMenuGroup> <ContextMenuItem> "Copy" <ContextMenuShortcut>"⌘C"</ContextMenuShortcut> </ContextMenuItem> <ContextMenuItem> "Cut" <ContextMenuShortcut>"⌘X"</ContextMenuShortcut> </ContextMenuItem> </ContextMenuGroup> <ContextMenuSub> <ContextMenuSubTrigger>"More Tools"</ContextMenuSubTrigger> <ContextMenuSubContent> <ContextMenuGroup> <ContextMenuItem>"Save Page..."</ContextMenuItem> <ContextMenuItem>"Create Shortcut..."</ContextMenuItem> <ContextMenuItem>"Name Window..."</ContextMenuItem> </ContextMenuGroup> <ContextMenuSeparator /> <ContextMenuGroup> <ContextMenuItem>"Developer Tools"</ContextMenuItem> </ContextMenuGroup> <ContextMenuSeparator /> <ContextMenuGroup> <ContextMenuItem variant="destructive">"Delete"</ContextMenuItem> </ContextMenuGroup> </ContextMenuSubContent> </ContextMenuSub> </ContextMenuContent> </ContextMenu> } }
Shortcuts
Add MenuShortcut to show keyboard hints.
use leptos::prelude::*; use singlestage::*; #[component] pub fn ContextShortcutsExample() -> impl IntoView { view! { <ContextMenu> <ContextMenuTrigger class="flex h-[150px] w-[300px] items-center justify-center rounded-xl border border-dashed text-sm"> <span class="pointer-fine:hidden">"Long press here"</span> <span class="pointer-coarse:hidden">"Right click here"</span> </ContextMenuTrigger> <ContextMenuContent> <ContextMenuGroup> <ContextMenuItem> "Back" <ContextMenuShortcut>"⌘["</ContextMenuShortcut> </ContextMenuItem> <ContextMenuItem disabled=true> "Forward" <ContextMenuShortcut>"⌘]"</ContextMenuShortcut> </ContextMenuItem> <ContextMenuItem> "Reload" <ContextMenuShortcut>"⌘R"</ContextMenuShortcut> </ContextMenuItem> </ContextMenuGroup> <ContextMenuSeparator /> <ContextMenuGroup> <ContextMenuItem> "Save" <ContextMenuShortcut>"⌘S"</ContextMenuShortcut> </ContextMenuItem> <ContextMenuItem> "Save As..." <ContextMenuShortcut>"⇧⌘S"</ContextMenuShortcut> </ContextMenuItem> </ContextMenuGroup> </ContextMenuContent> </ContextMenu> } }
Groups
Group related actions and separate them with dividers.
use leptos::prelude::*; use singlestage::*; #[component] pub fn ContextGroupsExample() -> impl IntoView { view! { <ContextMenu> <ContextMenuTrigger class="flex h-[150px] w-[300px] items-center justify-center rounded-xl border border-dashed text-sm"> <span class="pointer-fine:hidden">"Long press here"</span> <span class="pointer-coarse:hidden">"Right click here"</span> </ContextMenuTrigger> <ContextMenuContent> <ContextMenuGroup> <ContextMenuLabel>"File"</ContextMenuLabel> <ContextMenuItem> "New File" <ContextMenuShortcut>"⌘N"</ContextMenuShortcut> </ContextMenuItem> <ContextMenuItem> "Open File" <ContextMenuShortcut>"⌘O"</ContextMenuShortcut> </ContextMenuItem> <ContextMenuItem> "Save" <ContextMenuShortcut>"⌘S"</ContextMenuShortcut> </ContextMenuItem> </ContextMenuGroup> <ContextMenuSeparator /> <ContextMenuGroup> <ContextMenuLabel>"Edit"</ContextMenuLabel> <ContextMenuItem> "Undo" <ContextMenuShortcut>"⌘Z"</ContextMenuShortcut> </ContextMenuItem> <ContextMenuItem> "Redo" <ContextMenuShortcut>"⇧⌘Z"</ContextMenuShortcut> </ContextMenuItem> </ContextMenuGroup> <ContextMenuSeparator /> <ContextMenuGroup> <ContextMenuItem> "Cut" <ContextMenuShortcut>"⌘X"</ContextMenuShortcut> </ContextMenuItem> <ContextMenuItem> "Copy" <ContextMenuShortcut>"⌘C"</ContextMenuShortcut> </ContextMenuItem> <ContextMenuItem> "Paste" <ContextMenuShortcut>"⌘V"</ContextMenuShortcut> </ContextMenuItem> </ContextMenuGroup> <ContextMenuSeparator /> <ContextMenuGroup> <ContextMenuItem variant="destructive"> "Delete" <ContextMenuShortcut>"⌫"</ContextMenuShortcut> </ContextMenuItem> </ContextMenuGroup> </ContextMenuContent> </ContextMenu> } }
Icons
Combine icons with labels for quick scanning.
use leptos::prelude::*; use singlestage::*; #[component] pub fn ContextIconsExample() -> impl IntoView { view! { <ContextMenu> <ContextMenuTrigger class="flex h-[150px] w-[300px] items-center justify-center rounded-xl border border-dashed text-sm"> <span class="pointer-fine:hidden">"Long press here"</span> <span class="pointer-coarse:hidden">"Right click here"</span> </ContextMenuTrigger> <ContextMenuContent> <ContextMenuGroup> <ContextMenuItem>{icon!(icondata::LuCopy)} "Copy"</ContextMenuItem> <ContextMenuItem>{icon!(icondata::LuScissors)} "Cut"</ContextMenuItem> <ContextMenuItem>{icon!(icondata::LuClipboardPaste)} "Paste"</ContextMenuItem> </ContextMenuGroup> <ContextMenuSeparator /> <ContextMenuGroup> <ContextMenuItem variant="destructive"> {icon!(icondata::LuTrash)} "Delete" </ContextMenuItem> </ContextMenuGroup> </ContextMenuContent> </ContextMenu> } }
Checkboxes
Checkboxes can be used in context menus.
use leptos::prelude::*; use singlestage::*; #[component] pub fn ContextCheckboxesExample() -> impl IntoView { let value = RwSignal::new(vec!["bookmarks".to_string(), "devtools".to_string()]); view! { <ContextMenu> <ContextMenuTrigger class="flex h-[150px] w-[300px] items-center justify-center rounded-xl border border-dashed text-sm"> <span class="pointer-fine:hidden">"Long press here"</span> <span class="pointer-coarse:hidden">"Right click here"</span> </ContextMenuTrigger> <ContextMenuContent> <ContextMenuGroup> <ContextMenuCheckboxGroup value> <ContextMenuCheckboxItem value="bookmarks"> "Show Bookmarks Bar" </ContextMenuCheckboxItem> <ContextMenuCheckboxItem value="urls"> "Show Full URLs" </ContextMenuCheckboxItem> <ContextMenuCheckboxItem value="devtools"> "Show Developer Tools" </ContextMenuCheckboxItem> </ContextMenuCheckboxGroup> </ContextMenuGroup> </ContextMenuContent> </ContextMenu> } }
Radio
Radio buttons can be used in context menus.
use leptos::prelude::*; use singlestage::*; #[component] pub fn ContextRadioExample() -> impl IntoView { let user = RwSignal::new("pedro".to_string()); let theme = RwSignal::new("light".to_string()); view! { <ContextMenu> <ContextMenuTrigger class="flex h-[150px] w-[300px] items-center justify-center rounded-xl border border-dashed text-sm"> <span class="pointer-fine:hidden">"Long press here"</span> <span class="pointer-coarse:hidden">"Right click here"</span> </ContextMenuTrigger> <ContextMenuContent> <ContextMenuGroup> <ContextMenuLabel>"People"</ContextMenuLabel> <ContextMenuRadioGroup value=user> <ContextMenuRadioItem value="pedro">"Pedro Duarte"</ContextMenuRadioItem> <ContextMenuRadioItem value="colm">"Colm Tuite"</ContextMenuRadioItem> </ContextMenuRadioGroup> </ContextMenuGroup> <ContextMenuSeparator /> <ContextMenuGroup> <ContextMenuLabel>"Theme"</ContextMenuLabel> <ContextMenuRadioGroup value=theme> <ContextMenuRadioItem value="light">"Light"</ContextMenuRadioItem> <ContextMenuRadioItem value="dark">"Dark"</ContextMenuRadioItem> <ContextMenuRadioItem value="system">"System"</ContextMenuRadioItem> </ContextMenuRadioGroup> </ContextMenuGroup> </ContextMenuContent> </ContextMenu> } }
Destructive
Use the destructive variant for irreversible actions.
use leptos::prelude::*; use singlestage::*; #[component] pub fn ContextDestructiveExample() -> impl IntoView { view! { <ContextMenu> <ContextMenuTrigger class="flex h-[150px] w-[300px] items-center justify-center rounded-xl border border-dashed text-sm"> <span class="pointer-fine:hidden">"Long press here"</span> <span class="pointer-coarse:hidden">"Right click here"</span> </ContextMenuTrigger> <ContextMenuContent> <ContextMenuGroup> <ContextMenuItem>{icon!(icondata::LuPencil)} "Edit"</ContextMenuItem> <ContextMenuItem>{icon!(icondata::LuShare)} "Share"</ContextMenuItem> </ContextMenuGroup> <ContextMenuSeparator /> <ContextMenuGroup> <ContextMenuItem variant="destructive"> {icon!(icondata::LuTrash)} "Delete" </ContextMenuItem> </ContextMenuGroup> </ContextMenuContent> </ContextMenu> } }
Anatomy
Import all parts and piece them together.
use leptos::prelude::*; use singlestage::*; #[component] pub fn ContextMenuAnatomy() -> impl IntoView { view! { <ContextMenu> <ContextMenuTrigger> <Button /> </ContextMenuTrigger> <ContextMenuContent> <ContextMenuGroup> <ContextMenuLabel /> <ContextMenuItem> <ContextMenuShortcut /> </ContextMenuItem> </ContextMenuGroup> <ContextMenuSeparator /> <ContextMenuSub> <ContextMenuSubTrigger /> <ContextMenuSubContent> <ContextMenuGroup> <ContextMenuCheckboxGroup> <ContextMenuCheckboxItem /> </ContextMenuCheckboxGroup> </ContextMenuGroup> <ContextMenuSeparator /> <ContextMenuGroup> <ContextMenuRadioGroup> <ContextMenuRadioItem /> </ContextMenuRadioGroup> </ContextMenuGroup> </ContextMenuSubContent> </ContextMenuSub> </ContextMenuContent> </ContextMenu> } }
API Reference
ContextMenuCheckboxGroup
A checkbox group component for context menus.
| Name | Type | Default | Description |
|---|---|---|---|
| invalid | bool | false | A reactive signal that toggles whether all the children Checkboxes appear invalid or not. |
| value | Vec<String> | [] | A dynamic list of all the values of checked children Checkboxes. |
ContextMenuCheckboxItem
A checkbox item for context menus.
| Name | Type | Default | Description |
|---|---|---|---|
| checked | bool | false | A reactive signal coupled to the checkbox's checked value. |
| disabled | bool | false | Controls whether the item appears disabled or not. |
| dismiss | bool | true | Toggle whether clicking this item dismisses the parent menu. |
| inset | bool | false | Set whether or not this element should display inset from its normal position. |
| variant | String | "" | Set the display variant of the item. Accepted values: "destructive". |
ContextMenuCheckboxGroup
A checkbox group component for context menus.
| Name | Type | Default | Description |
|---|---|---|---|
| invalid | bool | false | Renders the group with invalid styling. |
| value | String | "" | A reactive signal coupled to the current selected value of the group. |
ContextMenuContent
The component that pops out when the context menu is open.
| Name | Type | Default | Description |
|---|---|---|---|
| align | String | "start" | Set how to align the popover. Accepted values: "start" | "center" | "end" |
| side | String | "bottom" | Set which side the popover opens relative to the trigger point. Accepted values: "top" | "right" | "bottom" | "left"" |
ContextMenuItem
Contains a context menu item.
| Name | Type | Default | Description |
|---|---|---|---|
| as_child | bool | false | This component will render without styling. |
| disabled | bool | false | Controls whether the item appears disabled and is clickable. |
| dismiss | bool | true | Toggle whether clicking this item dismisses the parent menu. |
| inset | bool | false | Set whether or not this element should display inset from its normal position. |
| variant | String | "" | Set the display variant of the item. Accepted values: "destructive". |
ContextMenuLabel
Labels groups of menu items.
| Name | Type | Default | Description |
|---|---|---|---|
| disabled | bool | false | Renders the label with disabled styling. |
| inset | bool | false | Set whether or not this element should display inset from its normal position. |
| invalid | bool | false | Renders the label with invalid styling. |
| label_for | String | "" | Use this to explicitly set the id of the labeled element. |
ContextMenuRadioItem
A radio item for context menus.
| Name | Type | Default | Description |
|---|---|---|---|
| checked | bool | false | A reactive signal coupled to the radio's checked value. |
| disabled | bool | false | Controls whether the item appears disabled or not. |
| dismiss | bool | true | Toggle whether clicking this item dismisses the parent menu. |
| inset | bool | false | Set whether or not this element should display inset from its normal position. |
| variant | String | "" | Set the display variant of the item. Accepted values: "destructive". |
ContextMenuRadioGroup
A radio group component for context menus.
| Name | Type | Default | Description |
|---|---|---|---|
| default | String | "" | Set or update the default value. |
| invalid | bool | false | Renders the group with invalid styling. |
| value | String | "" | A reactive signal coupled to the current selected value of the radio group. |
ContextMenuSeparator
Visually separates groups of menu items.
| Name | Type | Default | Description |
|---|---|---|---|
| orientation | String | "horizontal" | Specify the orientation of the separator. Accepted values: "horizontal" | "vertical". |
ContextMenuShortcut
Displays next to the item content and indicates keyboard shortcuts.
ContextMenuTrigger
Defines the area where the context menu can be triggered.
ContextMenuSub
Contains all the parts of a sub menu.
| Name | Type | Default | Description |
|---|---|---|---|
| open | bool | false | Reactive signal that can remotely control the open state of the popover but is not coupled to the actual state of the popover. |
ContextMenuSubContent
The component that pops out when the sub trigger is triggered.
| Name | Type | Default | Description |
|---|---|---|---|
| align | String | "start" | Set how to align the popover. Accepted values: "start" | "center" | "end" |
| side | String | "bottom" | Set which side the popover opens relative to the trigger point. Accepted values: "top" | "right" | "bottom" | "left"" |
ContextMenuSubTrigger
A context menu item that triggers a sub menu.
| Name | Type | Default | Description |
|---|---|---|---|
| disabled | bool | false | Controls whether the item appears disabled or not. |
| inset | bool | false | Set whether or not this element should display inset from its normal position. |
| variant | String | "" | Set the display variant of the item. Accepted values: "destructive". |