Add .visible_on_hover
helper method (#3639)
This PR adds a `.visible_on_hover` helper method that can be used to make an element only visible on hover. I noticed we were repeating this similar stanza in a bunch of different spots: ```rs some_element .invisible() .group_hover("", |style| style.visible()) ``` so it seemed like a nice thing to factor out into a reusable utility. Release Notes: - N/A
This commit is contained in:
parent
d59de96921
commit
137e4e9251
9 changed files with 37 additions and 37 deletions
|
@ -21,10 +21,7 @@ use settings::{Settings, SettingsStore};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use theme::ActiveTheme as _;
|
use theme::ActiveTheme as _;
|
||||||
use time::{OffsetDateTime, UtcOffset};
|
use time::{OffsetDateTime, UtcOffset};
|
||||||
use ui::{
|
use ui::{prelude::*, Avatar, Button, Icon, IconButton, Label, Tooltip};
|
||||||
h_stack, prelude::WindowContext, v_stack, Avatar, Button, ButtonCommon as _, Clickable, Icon,
|
|
||||||
IconButton, Label, Tooltip,
|
|
||||||
};
|
|
||||||
use util::{ResultExt, TryFutureExt};
|
use util::{ResultExt, TryFutureExt};
|
||||||
use workspace::{
|
use workspace::{
|
||||||
dock::{DockPosition, Panel, PanelEvent},
|
dock::{DockPosition, Panel, PanelEvent},
|
||||||
|
@ -382,12 +379,11 @@ impl ChatPanel {
|
||||||
.child(text.element("body".into(), cx))
|
.child(text.element("body".into(), cx))
|
||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
.invisible()
|
|
||||||
.absolute()
|
.absolute()
|
||||||
.top_1()
|
.top_1()
|
||||||
.right_2()
|
.right_2()
|
||||||
.w_8()
|
.w_8()
|
||||||
.group_hover("", |this| this.visible())
|
.visible_on_hover("")
|
||||||
.child(render_remove(message_id_to_remove, cx)),
|
.child(render_remove(message_id_to_remove, cx)),
|
||||||
)
|
)
|
||||||
.into_any()
|
.into_any()
|
||||||
|
|
|
@ -2290,8 +2290,7 @@ impl CollabPanel {
|
||||||
Section::ActiveCall => channel_link.map(|channel_link| {
|
Section::ActiveCall => channel_link.map(|channel_link| {
|
||||||
let channel_link_copy = channel_link.clone();
|
let channel_link_copy = channel_link.clone();
|
||||||
div()
|
div()
|
||||||
.invisible()
|
.visible_on_hover("section-header")
|
||||||
.group_hover("section-header", |this| this.visible())
|
|
||||||
.child(
|
.child(
|
||||||
IconButton::new("channel-link", Icon::Copy)
|
IconButton::new("channel-link", Icon::Copy)
|
||||||
.icon_size(IconSize::Small)
|
.icon_size(IconSize::Small)
|
||||||
|
@ -2381,21 +2380,17 @@ impl CollabPanel {
|
||||||
})
|
})
|
||||||
.when(!calling, |el| {
|
.when(!calling, |el| {
|
||||||
el.child(
|
el.child(
|
||||||
div()
|
div().visible_on_hover("").child(
|
||||||
.id("remove_contact")
|
IconButton::new("remove_contact", Icon::Close)
|
||||||
.invisible()
|
.icon_color(Color::Muted)
|
||||||
.group_hover("", |style| style.visible())
|
.tooltip(|cx| Tooltip::text("Remove Contact", cx))
|
||||||
.child(
|
.on_click(cx.listener({
|
||||||
IconButton::new("remove_contact", Icon::Close)
|
let github_login = github_login.clone();
|
||||||
.icon_color(Color::Muted)
|
move |this, _, cx| {
|
||||||
.tooltip(|cx| Tooltip::text("Remove Contact", cx))
|
this.remove_contact(user_id, &github_login, cx);
|
||||||
.on_click(cx.listener({
|
}
|
||||||
let github_login = github_login.clone();
|
})),
|
||||||
move |this, _, cx| {
|
),
|
||||||
this.remove_contact(user_id, &github_login, cx);
|
|
||||||
}
|
|
||||||
})),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
@ -2626,8 +2621,7 @@ impl CollabPanel {
|
||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
.id("channel_chat")
|
.id("channel_chat")
|
||||||
.when(!has_messages_notification, |el| el.invisible())
|
.when(!has_messages_notification, |el| el.visible_on_hover(""))
|
||||||
.group_hover("", |style| style.visible())
|
|
||||||
.child(
|
.child(
|
||||||
IconButton::new("channel_chat", Icon::MessageBubbles)
|
IconButton::new("channel_chat", Icon::MessageBubbles)
|
||||||
.icon_color(if has_messages_notification {
|
.icon_color(if has_messages_notification {
|
||||||
|
@ -2644,8 +2638,7 @@ impl CollabPanel {
|
||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
.id("channel_notes")
|
.id("channel_notes")
|
||||||
.when(!has_notes_notification, |el| el.invisible())
|
.when(!has_notes_notification, |el| el.visible_on_hover(""))
|
||||||
.group_hover("", |style| style.visible())
|
|
||||||
.child(
|
.child(
|
||||||
IconButton::new("channel_notes", Icon::File)
|
IconButton::new("channel_notes", Icon::File)
|
||||||
.icon_color(if has_notes_notification {
|
.icon_color(if has_notes_notification {
|
||||||
|
|
|
@ -9766,8 +9766,7 @@ pub fn diagnostic_block_renderer(diagnostic: Diagnostic, is_valid: bool) -> Rend
|
||||||
div()
|
div()
|
||||||
.border()
|
.border()
|
||||||
.border_color(gpui::red())
|
.border_color(gpui::red())
|
||||||
.invisible()
|
.visible_on_hover(group_id)
|
||||||
.group_hover(group_id, |style| style.visible())
|
|
||||||
.child(
|
.child(
|
||||||
IconButton::new(copy_id.clone(), Icon::Copy)
|
IconButton::new(copy_id.clone(), Icon::Copy)
|
||||||
.icon_color(Color::Muted)
|
.icon_color(Color::Muted)
|
||||||
|
|
|
@ -111,10 +111,9 @@ impl RenderOnce for ListHeader {
|
||||||
.when_some(self.end_hover_slot, |this, end_hover_slot| {
|
.when_some(self.end_hover_slot, |this, end_hover_slot| {
|
||||||
this.child(
|
this.child(
|
||||||
div()
|
div()
|
||||||
.invisible()
|
|
||||||
.group_hover("list_header", |this| this.visible())
|
|
||||||
.absolute()
|
.absolute()
|
||||||
.right_0()
|
.right_0()
|
||||||
|
.visible_on_hover("list_header")
|
||||||
.child(end_hover_slot),
|
.child(end_hover_slot),
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -198,8 +198,7 @@ impl RenderOnce for ListItem {
|
||||||
.flex()
|
.flex()
|
||||||
.absolute()
|
.absolute()
|
||||||
.left(rems(-1.))
|
.left(rems(-1.))
|
||||||
.invisible()
|
.visible_on_hover("")
|
||||||
.group_hover("", |style| style.visible())
|
|
||||||
.child(Disclosure::new(is_open).on_toggle(self.on_toggle))
|
.child(Disclosure::new(is_open).on_toggle(self.on_toggle))
|
||||||
}))
|
}))
|
||||||
.child(
|
.child(
|
||||||
|
@ -226,8 +225,7 @@ impl RenderOnce for ListItem {
|
||||||
.absolute()
|
.absolute()
|
||||||
.right_2()
|
.right_2()
|
||||||
.top_0()
|
.top_0()
|
||||||
.invisible()
|
.visible_on_hover("list_item")
|
||||||
.group_hover("list_item", |this| this.visible())
|
|
||||||
.child(end_hover_slot),
|
.child(end_hover_slot),
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -158,7 +158,6 @@ impl RenderOnce for Tab {
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
h_stack()
|
h_stack()
|
||||||
.invisible()
|
|
||||||
.w_3()
|
.w_3()
|
||||||
.h_3()
|
.h_3()
|
||||||
.justify_center()
|
.justify_center()
|
||||||
|
@ -167,7 +166,7 @@ impl RenderOnce for Tab {
|
||||||
TabCloseSide::Start => this.left_1(),
|
TabCloseSide::Start => this.left_1(),
|
||||||
TabCloseSide::End => this.right_1(),
|
TabCloseSide::End => this.right_1(),
|
||||||
})
|
})
|
||||||
.group_hover("", |style| style.visible())
|
.visible_on_hover("")
|
||||||
.children(self.end_slot),
|
.children(self.end_slot),
|
||||||
)
|
)
|
||||||
.children(self.children),
|
.children(self.children),
|
||||||
|
|
|
@ -9,6 +9,7 @@ pub use crate::clickable::*;
|
||||||
pub use crate::disableable::*;
|
pub use crate::disableable::*;
|
||||||
pub use crate::fixed::*;
|
pub use crate::fixed::*;
|
||||||
pub use crate::selectable::*;
|
pub use crate::selectable::*;
|
||||||
|
pub use crate::visible_on_hover::*;
|
||||||
pub use crate::{h_stack, v_stack};
|
pub use crate::{h_stack, v_stack};
|
||||||
pub use crate::{Button, ButtonSize, ButtonStyle, IconButton};
|
pub use crate::{Button, ButtonSize, ButtonStyle, IconButton};
|
||||||
pub use crate::{ButtonCommon, Color, StyledExt};
|
pub use crate::{ButtonCommon, Color, StyledExt};
|
||||||
|
|
|
@ -21,6 +21,7 @@ mod selectable;
|
||||||
mod styled_ext;
|
mod styled_ext;
|
||||||
mod styles;
|
mod styles;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
mod visible_on_hover;
|
||||||
|
|
||||||
pub use clickable::*;
|
pub use clickable::*;
|
||||||
pub use components::*;
|
pub use components::*;
|
||||||
|
@ -30,3 +31,4 @@ pub use prelude::*;
|
||||||
pub use selectable::*;
|
pub use selectable::*;
|
||||||
pub use styled_ext::*;
|
pub use styled_ext::*;
|
||||||
pub use styles::*;
|
pub use styles::*;
|
||||||
|
pub use visible_on_hover::*;
|
||||||
|
|
13
crates/ui2/src/visible_on_hover.rs
Normal file
13
crates/ui2/src/visible_on_hover.rs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
use gpui::{InteractiveElement, SharedString, Styled};
|
||||||
|
|
||||||
|
pub trait VisibleOnHover: InteractiveElement + Styled + Sized {
|
||||||
|
/// Sets the element to only be visible when the specified group is hovered.
|
||||||
|
///
|
||||||
|
/// Pass `""` as the `group_name` to use the global group.
|
||||||
|
fn visible_on_hover(self, group_name: impl Into<SharedString>) -> Self {
|
||||||
|
self.invisible()
|
||||||
|
.group_hover(group_name, |style| style.visible())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: InteractiveElement + Styled> VisibleOnHover for E {}
|
Loading…
Add table
Add a link
Reference in a new issue