menu: Add external link icon to link menu item. (#734)
<img width="403" alt="image" src="https://github.com/user-attachments/assets/ad6682b6-2114-4f55-be84-d06c02ae401e" />
This commit is contained in:
parent
e0f4a7d3cd
commit
f650491605
4 changed files with 46 additions and 3 deletions
14
assets/icons/external-link.svg
Normal file
14
assets/icons/external-link.svg
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="lucide lucide-external-link"
|
||||||
|
><path d="M15 3h6v6" /><path d="M10 14 21 3" /><path
|
||||||
|
d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"
|
||||||
|
/></svg>
|
||||||
|
After Width: | Height: | Size: 392 B |
|
|
@ -175,7 +175,9 @@ impl Render for PopupStory {
|
||||||
.min_h(px(400.))
|
.min_h(px(400.))
|
||||||
.context_menu({
|
.context_menu({
|
||||||
move |this, window, cx| {
|
move |this, window, cx| {
|
||||||
this.separator()
|
this.external_link_icon(false)
|
||||||
|
.link("About", "https://github.com/longbridge/gpui-component")
|
||||||
|
.separator()
|
||||||
.menu("Cut", Box::new(Cut))
|
.menu("Cut", Box::new(Cut))
|
||||||
.menu("Copy", Box::new(Copy))
|
.menu("Copy", Box::new(Copy))
|
||||||
.menu("Paste", Box::new(Paste))
|
.menu("Paste", Box::new(Paste))
|
||||||
|
|
@ -255,7 +257,9 @@ impl Render for PopupStory {
|
||||||
Button::new("popup-menu-1")
|
Button::new("popup-menu-1")
|
||||||
.icon(IconName::Ellipsis)
|
.icon(IconName::Ellipsis)
|
||||||
.popup_menu(move |this, window, cx| {
|
.popup_menu(move |this, window, cx| {
|
||||||
this.menu("Copy", Box::new(Copy))
|
this.link("About", "https://github.com/longbridge/gpui-component")
|
||||||
|
.separator()
|
||||||
|
.menu("Copy", Box::new(Copy))
|
||||||
.menu("Cut", Box::new(Cut))
|
.menu("Cut", Box::new(Cut))
|
||||||
.menu("Paste", Box::new(Paste))
|
.menu("Paste", Box::new(Paste))
|
||||||
.separator()
|
.separator()
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ pub enum IconName {
|
||||||
Delete,
|
Delete,
|
||||||
Ellipsis,
|
Ellipsis,
|
||||||
EllipsisVertical,
|
EllipsisVertical,
|
||||||
|
ExternalLink,
|
||||||
Eye,
|
Eye,
|
||||||
EyeOff,
|
EyeOff,
|
||||||
Frame,
|
Frame,
|
||||||
|
|
@ -110,6 +111,7 @@ impl IconName {
|
||||||
Self::Delete => "icons/delete.svg",
|
Self::Delete => "icons/delete.svg",
|
||||||
Self::Ellipsis => "icons/ellipsis.svg",
|
Self::Ellipsis => "icons/ellipsis.svg",
|
||||||
Self::EllipsisVertical => "icons/ellipsis-vertical.svg",
|
Self::EllipsisVertical => "icons/ellipsis-vertical.svg",
|
||||||
|
Self::ExternalLink => "icons/external-link.svg",
|
||||||
Self::Eye => "icons/eye.svg",
|
Self::Eye => "icons/eye.svg",
|
||||||
Self::EyeOff => "icons/eye-off.svg",
|
Self::EyeOff => "icons/eye-off.svg",
|
||||||
Self::Frame => "icons/frame.svg",
|
Self::Frame => "icons/frame.svg",
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ enum PopupMenuItem {
|
||||||
icon: Option<Icon>,
|
icon: Option<Icon>,
|
||||||
label: SharedString,
|
label: SharedString,
|
||||||
disabled: bool,
|
disabled: bool,
|
||||||
|
is_link: bool,
|
||||||
action: Option<Box<dyn Action>>,
|
action: Option<Box<dyn Action>>,
|
||||||
handler: Rc<dyn Fn(&mut Window, &mut App)>,
|
handler: Rc<dyn Fn(&mut Window, &mut App)>,
|
||||||
},
|
},
|
||||||
|
|
@ -107,6 +108,7 @@ pub struct PopupMenu {
|
||||||
bounds: Bounds<Pixels>,
|
bounds: Bounds<Pixels>,
|
||||||
|
|
||||||
scrollable: bool,
|
scrollable: bool,
|
||||||
|
external_link_icon: bool,
|
||||||
scroll_handle: ScrollHandle,
|
scroll_handle: ScrollHandle,
|
||||||
scroll_state: Rc<Cell<ScrollbarState>>,
|
scroll_state: Rc<Cell<ScrollbarState>>,
|
||||||
|
|
||||||
|
|
@ -144,6 +146,7 @@ impl PopupMenu {
|
||||||
scrollable: false,
|
scrollable: false,
|
||||||
scroll_handle: ScrollHandle::default(),
|
scroll_handle: ScrollHandle::default(),
|
||||||
scroll_state: Rc::new(Cell::new(ScrollbarState::default())),
|
scroll_state: Rc::new(Cell::new(ScrollbarState::default())),
|
||||||
|
external_link_icon: true,
|
||||||
_subscriptions,
|
_subscriptions,
|
||||||
};
|
};
|
||||||
f(menu, window, cx)
|
f(menu, window, cx)
|
||||||
|
|
@ -176,6 +179,12 @@ impl PopupMenu {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the menu to show external link icon, default is true.
|
||||||
|
pub fn external_link_icon(mut self, visible: bool) -> Self {
|
||||||
|
self.external_link_icon = visible;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Add Menu Item
|
/// Add Menu Item
|
||||||
pub fn menu(self, label: impl Into<SharedString>, action: Box<dyn Action>) -> Self {
|
pub fn menu(self, label: impl Into<SharedString>, action: Box<dyn Action>) -> Self {
|
||||||
self.menu_with_disabled(label, action, false)
|
self.menu_with_disabled(label, action, false)
|
||||||
|
|
@ -216,6 +225,7 @@ impl PopupMenu {
|
||||||
label: label.into(),
|
label: label.into(),
|
||||||
disabled,
|
disabled,
|
||||||
action: None,
|
action: None,
|
||||||
|
is_link: true,
|
||||||
handler: Rc::new(move |_, cx| cx.open_url(&href)),
|
handler: Rc::new(move |_, cx| cx.open_url(&href)),
|
||||||
});
|
});
|
||||||
self
|
self
|
||||||
|
|
@ -245,6 +255,7 @@ impl PopupMenu {
|
||||||
label: label.into(),
|
label: label.into(),
|
||||||
disabled,
|
disabled,
|
||||||
action: None,
|
action: None,
|
||||||
|
is_link: true,
|
||||||
handler: Rc::new(move |_, cx| cx.open_url(&href)),
|
handler: Rc::new(move |_, cx| cx.open_url(&href)),
|
||||||
});
|
});
|
||||||
self
|
self
|
||||||
|
|
@ -499,6 +510,7 @@ impl PopupMenu {
|
||||||
label: label.into(),
|
label: label.into(),
|
||||||
disabled,
|
disabled,
|
||||||
action: Some(action.boxed_clone()),
|
action: Some(action.boxed_clone()),
|
||||||
|
is_link: false,
|
||||||
handler: self.wrap_handler(action),
|
handler: self.wrap_handler(action),
|
||||||
});
|
});
|
||||||
self
|
self
|
||||||
|
|
@ -730,8 +742,10 @@ impl PopupMenu {
|
||||||
label,
|
label,
|
||||||
action,
|
action,
|
||||||
disabled,
|
disabled,
|
||||||
|
is_link,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
|
let show_link_icon = *is_link && self.external_link_icon;
|
||||||
let action = action.as_ref().map(|action| action.boxed_clone());
|
let action = action.as_ref().map(|action| action.boxed_clone());
|
||||||
let key = Self::render_keybinding(action, window, cx);
|
let key = Self::render_keybinding(action, window, cx);
|
||||||
|
|
||||||
|
|
@ -753,7 +767,16 @@ impl PopupMenu {
|
||||||
.gap_2()
|
.gap_2()
|
||||||
.items_center()
|
.items_center()
|
||||||
.justify_between()
|
.justify_between()
|
||||||
.child(label.clone())
|
.when(!show_link_icon, |this| this.child(label.clone()))
|
||||||
|
.when(show_link_icon, |this| {
|
||||||
|
this.child(
|
||||||
|
h_flex().gap_1p5().child(label.clone()).child(
|
||||||
|
Icon::new(IconName::ExternalLink)
|
||||||
|
.xsmall()
|
||||||
|
.text_color(cx.theme().muted_foreground),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
})
|
||||||
.children(key),
|
.children(key),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue