use gpui::{AnyView, App, Context, IntoElement, SharedString, Window, div, prelude::*, px};
use crate::widgets::Content;
use theme::Theme;
use crate::{popover, surface::Surfaced as _};
pub struct HoverCard {
title: SharedString,
body: SharedString,
initials: Option<SharedString>,
meta: Option<SharedString>,
}
impl HoverCard {
pub fn summary(
title: impl Into<SharedString>,
body: impl Into<SharedString>,
_window: &mut Window,
cx: &mut App,
) -> AnyView {
let (title, body) = (title.into(), body.into());
cx.new(|_| Self {
title,
body,
initials: None,
meta: None,
})
.into()
}
pub fn person(
initials: impl Into<SharedString>,
name: impl Into<SharedString>,
body: impl Into<SharedString>,
meta: impl Into<SharedString>,
_window: &mut Window,
cx: &mut App,
) -> AnyView {
let (initials, name, body, meta) = (initials.into(), name.into(), body.into(), meta.into());
cx.new(|_| Self {
title: name,
body,
initials: Some(initials),
meta: Some(meta),
})
.into()
}
}
impl Render for HoverCard {
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let theme = Theme::of(cx).clone();
let heading = div()
.flex()
.flex_row()
.items_center()
.gap(px(10.0))
.when_some(self.initials.clone(), |row, initials| {
row.child(theme.avatar(initials))
})
.child(
div()
.text_size(px(13.0))
.font_weight(gpui::FontWeight::MEDIUM)
.text_color(theme.text)
.child(self.title.clone()),
);
popover::popover_card(&theme)
.w(px(280.0))
.p(px(12.0))
.flex()
.flex_col()
.gap(px(8.0))
.child(heading)
.child(
div()
.text_size(px(12.5))
.line_height(px(18.0))
.text_color(theme.text_muted)
.child(self.body.clone()),
)
.when_some(self.meta.clone(), |card, meta| {
card.child(
div()
.text_size(px(11.5))
.text_color(theme.text_faint)
.child(meta),
)
})
.surface(&theme, theme.popover_surface)
}
}