maud_ui/primitives/context_menu.rs
1//! Context menu component — right-click menu overlay
2
3use maud::{html, Markup};
4use crate::primitives::menu::{MenuEntry, MenuItem, render_entry};
5
6/// Context menu rendering properties
7#[derive(Debug, Clone)]
8pub struct Props {
9 /// Unique identifier for the menu
10 pub id: String,
11 /// Content that can be right-clicked to trigger the menu
12 pub trigger: Markup,
13 /// Menu entries (items, separators, and labels)
14 pub items: Vec<MenuEntry>,
15}
16
17/// Render a context menu with the given properties
18pub fn render(props: Props) -> Markup {
19 html! {
20 div.mui-context-menu data-mui="context-menu" {
21 div.mui-context-menu__region {
22 (props.trigger)
23 }
24 div.mui-context-menu__content
25 id=(format!("{}-menu", props.id))
26 role="menu"
27 hidden
28 style="position: fixed; top: 0; left: 0;"
29 {
30 @for entry in &props.items {
31 (render_entry(entry))
32 }
33 }
34 }
35 }
36}
37
38/// Showcase context menu component
39pub fn showcase() -> Markup {
40 html! {
41 div.mui-showcase__grid {
42 div {
43 p.mui-showcase__caption { "Right-click the area below" }
44 div.mui-showcase__row {
45 (render(Props {
46 id: "demo-ctx-1".into(),
47 trigger: html! {
48 div.mui-context-menu-demo {
49 "Right-click me"
50 }
51 },
52 items: vec![
53 MenuEntry::Item(MenuItem {
54 label: "Cut".into(),
55 action: "cut".into(),
56 disabled: false,
57 destructive: false,
58 shortcut: Some("\u{2318}X".into()),
59 }),
60 MenuEntry::Item(MenuItem {
61 label: "Copy".into(),
62 action: "copy".into(),
63 disabled: false,
64 destructive: false,
65 shortcut: Some("\u{2318}C".into()),
66 }),
67 MenuEntry::Item(MenuItem {
68 label: "Paste".into(),
69 action: "paste".into(),
70 disabled: false,
71 destructive: false,
72 shortcut: Some("\u{2318}V".into()),
73 }),
74 MenuEntry::Separator,
75 MenuEntry::Item(MenuItem {
76 label: "Delete".into(),
77 action: "delete".into(),
78 disabled: false,
79 destructive: true,
80 shortcut: Some("\u{232b}".into()),
81 }),
82 ],
83 }))
84 }
85 }
86 }
87 }
88}