ui/components/
media_object.rs1use gpui::{AnyElement, FontWeight};
2
3use crate::Avatar;
4use crate::prelude::*;
5
6#[derive(IntoElement, RegisterComponent)]
9pub struct MediaObject {
10 media: AnyElement,
11 heading: SharedString,
12 description: Option<SharedString>,
13}
14
15impl MediaObject {
16 pub fn new(media: impl IntoElement, heading: impl Into<SharedString>) -> Self {
17 Self {
18 media: media.into_any_element(),
19 heading: heading.into(),
20 description: None,
21 }
22 }
23
24 pub fn description(mut self, description: impl Into<SharedString>) -> Self {
25 self.description = Some(description.into());
26 self
27 }
28}
29
30impl RenderOnce for MediaObject {
31 fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
32 h_flex().items_start().gap_4().child(self.media).child(
33 v_flex()
34 .gap_1()
35 .child(Label::new(self.heading).weight(FontWeight::MEDIUM))
36 .children(
37 self.description
38 .map(|d| Label::new(d).size(LabelSize::Small).color(Color::Muted)),
39 ),
40 )
41 }
42}
43
44impl Component for MediaObject {
45 fn scope() -> ComponentScope {
46 ComponentScope::DataDisplay
47 }
48
49 fn description() -> Option<&'static str> {
50 Some("A flex row pairing a media element (image/avatar) with a text block.")
51 }
52
53 fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
54 let example_avatar = "https://avatars.githubusercontent.com/u/1714999?v=4";
55
56 Some(
57 v_flex()
58 .gap_4()
59 .child(MediaObject::new(
60 Avatar::new(example_avatar).size(px(48.)),
61 "Jane Cooper",
62 ))
63 .child(
64 MediaObject::new(Avatar::new(example_avatar).size(px(48.)), "Cody Fisher")
65 .description("Regional Paradigm Technician"),
66 )
67 .into_any_element(),
68 )
69 }
70}