1use crate::prelude::*;
2use crate::{v_stack, ButtonGroup};
3
4#[derive(RenderOnce)]
5pub struct Details<V: 'static> {
6 text: &'static str,
7 meta: Option<&'static str>,
8 actions: Option<ButtonGroup<V>>,
9}
10
11impl<V: 'static> Component<V> for Details<V> {
12 type Rendered = Div<V>;
13
14 fn render(self, view: &mut V, cx: &mut ViewContext<V>) -> Self::Rendered {
15 v_stack()
16 .p_1()
17 .gap_0p5()
18 .text_ui_sm()
19 .text_color(cx.theme().colors().text)
20 .size_full()
21 .child(self.text)
22 .children(self.meta.map(|m| m))
23 .children(self.actions.map(|a| a))
24 }
25}
26
27impl<V: 'static> Details<V> {
28 pub fn new(text: &'static str) -> Self {
29 Self {
30 text,
31 meta: None,
32 actions: None,
33 }
34 }
35
36 pub fn meta_text(mut self, meta: &'static str) -> Self {
37 self.meta = Some(meta);
38 self
39 }
40
41 pub fn actions(mut self, actions: ButtonGroup<V>) -> Self {
42 self.actions = Some(actions);
43 self
44 }
45}
46
47use gpui::{Div, RenderOnce};
48#[cfg(feature = "stories")]
49pub use stories::*;
50
51#[cfg(feature = "stories")]
52mod stories {
53 use super::*;
54 use crate::{Button, Story};
55 use gpui::{Div, Render};
56
57 pub struct DetailsStory;
58
59 impl Render<Self> for DetailsStory {
60 type Element = Div<Self>;
61
62 fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
63 Story::container(cx)
64 .child(Story::title_for::<_, Details<Self>>(cx))
65 .child(Story::label(cx, "Default"))
66 .child(Details::new("The quick brown fox jumps over the lazy dog"))
67 .child(Story::label(cx, "With meta"))
68 .child(
69 Details::new("The quick brown fox jumps over the lazy dog")
70 .meta_text("Sphinx of black quartz, judge my vow."),
71 )
72 .child(Story::label(cx, "With meta and actions"))
73 .child(
74 Details::new("The quick brown fox jumps over the lazy dog")
75 .meta_text("Sphinx of black quartz, judge my vow.")
76 .actions(ButtonGroup::new(vec![
77 Button::new("Decline"),
78 Button::new("Accept").variant(crate::ButtonVariant::Filled),
79 ])),
80 )
81 }
82 }
83}