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:
Marshall Bowers 2023-12-13 19:12:20 -05:00 committed by GitHub
parent d59de96921
commit 137e4e9251
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 37 additions and 37 deletions

View file

@ -21,10 +21,7 @@ use settings::{Settings, SettingsStore};
use std::sync::Arc;
use theme::ActiveTheme as _;
use time::{OffsetDateTime, UtcOffset};
use ui::{
h_stack, prelude::WindowContext, v_stack, Avatar, Button, ButtonCommon as _, Clickable, Icon,
IconButton, Label, Tooltip,
};
use ui::{prelude::*, Avatar, Button, Icon, IconButton, Label, Tooltip};
use util::{ResultExt, TryFutureExt};
use workspace::{
dock::{DockPosition, Panel, PanelEvent},
@ -382,12 +379,11 @@ impl ChatPanel {
.child(text.element("body".into(), cx))
.child(
div()
.invisible()
.absolute()
.top_1()
.right_2()
.w_8()
.group_hover("", |this| this.visible())
.visible_on_hover("")
.child(render_remove(message_id_to_remove, cx)),
)
.into_any()

View file

@ -2290,8 +2290,7 @@ impl CollabPanel {
Section::ActiveCall => channel_link.map(|channel_link| {
let channel_link_copy = channel_link.clone();
div()
.invisible()
.group_hover("section-header", |this| this.visible())
.visible_on_hover("section-header")
.child(
IconButton::new("channel-link", Icon::Copy)
.icon_size(IconSize::Small)
@ -2381,11 +2380,7 @@ impl CollabPanel {
})
.when(!calling, |el| {
el.child(
div()
.id("remove_contact")
.invisible()
.group_hover("", |style| style.visible())
.child(
div().visible_on_hover("").child(
IconButton::new("remove_contact", Icon::Close)
.icon_color(Color::Muted)
.tooltip(|cx| Tooltip::text("Remove Contact", cx))
@ -2626,8 +2621,7 @@ impl CollabPanel {
.child(
div()
.id("channel_chat")
.when(!has_messages_notification, |el| el.invisible())
.group_hover("", |style| style.visible())
.when(!has_messages_notification, |el| el.visible_on_hover(""))
.child(
IconButton::new("channel_chat", Icon::MessageBubbles)
.icon_color(if has_messages_notification {
@ -2644,8 +2638,7 @@ impl CollabPanel {
.child(
div()
.id("channel_notes")
.when(!has_notes_notification, |el| el.invisible())
.group_hover("", |style| style.visible())
.when(!has_notes_notification, |el| el.visible_on_hover(""))
.child(
IconButton::new("channel_notes", Icon::File)
.icon_color(if has_notes_notification {

View file

@ -9766,8 +9766,7 @@ pub fn diagnostic_block_renderer(diagnostic: Diagnostic, is_valid: bool) -> Rend
div()
.border()
.border_color(gpui::red())
.invisible()
.group_hover(group_id, |style| style.visible())
.visible_on_hover(group_id)
.child(
IconButton::new(copy_id.clone(), Icon::Copy)
.icon_color(Color::Muted)

View file

@ -111,10 +111,9 @@ impl RenderOnce for ListHeader {
.when_some(self.end_hover_slot, |this, end_hover_slot| {
this.child(
div()
.invisible()
.group_hover("list_header", |this| this.visible())
.absolute()
.right_0()
.visible_on_hover("list_header")
.child(end_hover_slot),
)
}),

View file

@ -198,8 +198,7 @@ impl RenderOnce for ListItem {
.flex()
.absolute()
.left(rems(-1.))
.invisible()
.group_hover("", |style| style.visible())
.visible_on_hover("")
.child(Disclosure::new(is_open).on_toggle(self.on_toggle))
}))
.child(
@ -226,8 +225,7 @@ impl RenderOnce for ListItem {
.absolute()
.right_2()
.top_0()
.invisible()
.group_hover("list_item", |this| this.visible())
.visible_on_hover("list_item")
.child(end_hover_slot),
)
}),

View file

@ -158,7 +158,6 @@ impl RenderOnce for Tab {
)
.child(
h_stack()
.invisible()
.w_3()
.h_3()
.justify_center()
@ -167,7 +166,7 @@ impl RenderOnce for Tab {
TabCloseSide::Start => this.left_1(),
TabCloseSide::End => this.right_1(),
})
.group_hover("", |style| style.visible())
.visible_on_hover("")
.children(self.end_slot),
)
.children(self.children),

View file

@ -9,6 +9,7 @@ pub use crate::clickable::*;
pub use crate::disableable::*;
pub use crate::fixed::*;
pub use crate::selectable::*;
pub use crate::visible_on_hover::*;
pub use crate::{h_stack, v_stack};
pub use crate::{Button, ButtonSize, ButtonStyle, IconButton};
pub use crate::{ButtonCommon, Color, StyledExt};

View file

@ -21,6 +21,7 @@ mod selectable;
mod styled_ext;
mod styles;
pub mod utils;
mod visible_on_hover;
pub use clickable::*;
pub use components::*;
@ -30,3 +31,4 @@ pub use prelude::*;
pub use selectable::*;
pub use styled_ext::*;
pub use styles::*;
pub use visible_on_hover::*;

View 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 {}