button.rs

  1use gpui2::elements::div;
  2use gpui2::geometry::rems;
  3use gpui2::{Element, IntoElement, ViewContext};
  4use strum::IntoEnumIterator;
  5use ui::prelude::*;
  6use ui::{h_stack, v_stack, Button, Icon, IconPosition, Label};
  7
  8use crate::story::Story;
  9
 10#[derive(Element, Default)]
 11pub struct ButtonStory {}
 12
 13impl ButtonStory {
 14    fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
 15        let states = InteractionState::iter();
 16
 17        Story::container(cx)
 18            .child(Story::title_for::<_, Button<V>>(cx))
 19            .child(
 20                div()
 21                    .flex()
 22                    .gap_8()
 23                    .child(
 24                        div()
 25                            .child(Story::label(cx, "Ghost (Default)"))
 26                            .child(h_stack().gap_2().children(states.clone().map(|state| {
 27                                v_stack()
 28                                    .gap_1()
 29                                    .child(
 30                                        Label::new(state.to_string())
 31                                            .color(ui::LabelColor::Muted)
 32                                            .size(ui::LabelSize::Small),
 33                                    )
 34                                    .child(
 35                                        Button::new("Label")
 36                                            .variant(ButtonVariant::Ghost)
 37                                            .state(state),
 38                                    )
 39                            })))
 40                            .child(Story::label(cx, "Ghost – Left Icon"))
 41                            .child(h_stack().gap_2().children(states.clone().map(|state| {
 42                                v_stack()
 43                                    .gap_1()
 44                                    .child(
 45                                        Label::new(state.to_string())
 46                                            .color(ui::LabelColor::Muted)
 47                                            .size(ui::LabelSize::Small),
 48                                    )
 49                                    .child(
 50                                        Button::new("Label")
 51                                            .variant(ButtonVariant::Ghost)
 52                                            .icon(Icon::Plus)
 53                                            .icon_position(IconPosition::Left)
 54                                            .state(state),
 55                                    )
 56                            })))
 57                            .child(Story::label(cx, "Ghost – Right Icon"))
 58                            .child(h_stack().gap_2().children(states.clone().map(|state| {
 59                                v_stack()
 60                                    .gap_1()
 61                                    .child(
 62                                        Label::new(state.to_string())
 63                                            .color(ui::LabelColor::Muted)
 64                                            .size(ui::LabelSize::Small),
 65                                    )
 66                                    .child(
 67                                        Button::new("Label")
 68                                            .variant(ButtonVariant::Ghost)
 69                                            .icon(Icon::Plus)
 70                                            .icon_position(IconPosition::Right)
 71                                            .state(state),
 72                                    )
 73                            }))),
 74                    )
 75                    .child(
 76                        div()
 77                            .child(Story::label(cx, "Filled"))
 78                            .child(h_stack().gap_2().children(states.clone().map(|state| {
 79                                v_stack()
 80                                    .gap_1()
 81                                    .child(
 82                                        Label::new(state.to_string())
 83                                            .color(ui::LabelColor::Muted)
 84                                            .size(ui::LabelSize::Small),
 85                                    )
 86                                    .child(
 87                                        Button::new("Label")
 88                                            .variant(ButtonVariant::Filled)
 89                                            .state(state),
 90                                    )
 91                            })))
 92                            .child(Story::label(cx, "Filled – Left Button"))
 93                            .child(h_stack().gap_2().children(states.clone().map(|state| {
 94                                v_stack()
 95                                    .gap_1()
 96                                    .child(
 97                                        Label::new(state.to_string())
 98                                            .color(ui::LabelColor::Muted)
 99                                            .size(ui::LabelSize::Small),
100                                    )
101                                    .child(
102                                        Button::new("Label")
103                                            .variant(ButtonVariant::Filled)
104                                            .icon(Icon::Plus)
105                                            .icon_position(IconPosition::Left)
106                                            .state(state),
107                                    )
108                            })))
109                            .child(Story::label(cx, "Filled – Right Button"))
110                            .child(h_stack().gap_2().children(states.clone().map(|state| {
111                                v_stack()
112                                    .gap_1()
113                                    .child(
114                                        Label::new(state.to_string())
115                                            .color(ui::LabelColor::Muted)
116                                            .size(ui::LabelSize::Small),
117                                    )
118                                    .child(
119                                        Button::new("Label")
120                                            .variant(ButtonVariant::Filled)
121                                            .icon(Icon::Plus)
122                                            .icon_position(IconPosition::Right)
123                                            .state(state),
124                                    )
125                            }))),
126                    )
127                    .child(
128                        div()
129                            .child(Story::label(cx, "Fixed With"))
130                            .child(h_stack().gap_2().children(states.clone().map(|state| {
131                                v_stack()
132                                    .gap_1()
133                                    .child(
134                                        Label::new(state.to_string())
135                                            .color(ui::LabelColor::Muted)
136                                            .size(ui::LabelSize::Small),
137                                    )
138                                    .child(
139                                        Button::new("Label")
140                                            .variant(ButtonVariant::Filled)
141                                            .state(state)
142                                            .width(Some(rems(6.).into())),
143                                    )
144                            })))
145                            .child(Story::label(cx, "Fixed With – Left Icon"))
146                            .child(h_stack().gap_2().children(states.clone().map(|state| {
147                                v_stack()
148                                    .gap_1()
149                                    .child(
150                                        Label::new(state.to_string())
151                                            .color(ui::LabelColor::Muted)
152                                            .size(ui::LabelSize::Small),
153                                    )
154                                    .child(
155                                        Button::new("Label")
156                                            .variant(ButtonVariant::Filled)
157                                            .state(state)
158                                            .icon(Icon::Plus)
159                                            .icon_position(IconPosition::Left)
160                                            .width(Some(rems(6.).into())),
161                                    )
162                            })))
163                            .child(Story::label(cx, "Fixed With – Right Icon"))
164                            .child(h_stack().gap_2().children(states.clone().map(|state| {
165                                v_stack()
166                                    .gap_1()
167                                    .child(
168                                        Label::new(state.to_string())
169                                            .color(ui::LabelColor::Muted)
170                                            .size(ui::LabelSize::Small),
171                                    )
172                                    .child(
173                                        Button::new("Label")
174                                            .variant(ButtonVariant::Filled)
175                                            .state(state)
176                                            .icon(Icon::Plus)
177                                            .icon_position(IconPosition::Right)
178                                            .width(Some(rems(6.).into())),
179                                    )
180                            }))),
181                    ),
182            )
183            .child(Story::label(cx, "Button with `on_click`"))
184            .child(
185                Button::new("Label")
186                    .variant(ButtonVariant::Ghost)
187                    // NOTE: There currently appears to be a bug in GPUI2 where only the last event handler will fire.
188                    // So adding additional buttons with `on_click`s after this one will cause this `on_click` to not fire.
189                    .on_click(|_view, _cx| println!("Button clicked.")),
190            )
191    }
192}