From 5083ab7694d7bc99ddd9c41f76c6c2313d9d6cac Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Thu, 21 Sep 2023 23:42:18 -0400 Subject: [PATCH] Add `TrafficLights` component (#3011) This PR adds a `TrafficLights` component for GPUI2. Screenshot 2023-09-21 at 11 32 10 PM Release Notes: - N/A --- crates/storybook/src/stories/components.rs | 1 + .../src/stories/components/traffic_lights.rs | 29 +++++++++++++++++ crates/storybook/src/storybook.rs | 6 ++++ crates/ui/src/components.rs | 2 ++ crates/ui/src/components/traffic_lights.rs | 30 ++++++++++++++++++ crates/ui/src/modules/title_bar.rs | 31 ++----------------- 6 files changed, 70 insertions(+), 29 deletions(-) create mode 100644 crates/storybook/src/stories/components/traffic_lights.rs create mode 100644 crates/ui/src/components/traffic_lights.rs diff --git a/crates/storybook/src/stories/components.rs b/crates/storybook/src/stories/components.rs index 5e3d309419..89ee5a92ea 100644 --- a/crates/storybook/src/stories/components.rs +++ b/crates/storybook/src/stories/components.rs @@ -1 +1,2 @@ pub mod facepile; +pub mod traffic_lights; diff --git a/crates/storybook/src/stories/components/traffic_lights.rs b/crates/storybook/src/stories/components/traffic_lights.rs new file mode 100644 index 0000000000..252caf99f6 --- /dev/null +++ b/crates/storybook/src/stories/components/traffic_lights.rs @@ -0,0 +1,29 @@ +use gpui2::elements::div; +use gpui2::style::StyleHelpers; +use gpui2::{rgb, Element, Hsla, IntoElement, ParentElement, ViewContext}; +use ui::{theme, traffic_lights}; + +#[derive(Element, Default)] +pub struct TrafficLightsStory {} + +impl TrafficLightsStory { + fn render(&mut self, _: &mut V, cx: &mut ViewContext) -> impl IntoElement { + let theme = theme(cx); + + div() + .size_full() + .flex() + .flex_col() + .pt_2() + .px_4() + .font("Zed Mono Extended") + .fill(rgb::(0x282c34)) + .child( + div() + .text_2xl() + .text_color(rgb::(0xffffff)) + .child(std::any::type_name::()), + ) + .child(traffic_lights()) + } +} diff --git a/crates/storybook/src/storybook.rs b/crates/storybook/src/storybook.rs index 089ff33049..b72c4a5681 100644 --- a/crates/storybook/src/storybook.rs +++ b/crates/storybook/src/storybook.rs @@ -14,6 +14,7 @@ use log::LevelFilter; use settings::{default_settings, SettingsStore}; use simplelog::SimpleLogger; use stories::components::facepile::FacepileStory; +use stories::components::traffic_lights::TrafficLightsStory; use stories::elements::avatar::AvatarStory; use ui::{ElementExt, Theme}; @@ -35,6 +36,7 @@ impl FromStr for Story { match s.to_ascii_lowercase().as_str() { "elements/avatar" => Ok(Self::Element(ElementStory::Avatar)), "components/facepile" => Ok(Self::Component(ComponentStory::Facepile)), + "components/traffic_lights" => Ok(Self::Component(ComponentStory::TrafficLights)), _ => Err(anyhow!("story not found for '{s}'")), } } @@ -48,6 +50,7 @@ enum ElementStory { #[derive(Debug, Clone, Copy)] enum ComponentStory { Facepile, + TrafficLights, } #[derive(Parser)] @@ -82,6 +85,9 @@ fn main() { Some(Story::Component(ComponentStory::Facepile)) => { view(|cx| render_story(&mut ViewContext::new(cx), FacepileStory::default())) } + Some(Story::Component(ComponentStory::TrafficLights)) => view(|cx| { + render_story(&mut ViewContext::new(cx), TrafficLightsStory::default()) + }), None => { view(|cx| render_story(&mut ViewContext::new(cx), WorkspaceElement::default())) } diff --git a/crates/ui/src/components.rs b/crates/ui/src/components.rs index a82d28eb8c..b400a491e4 100644 --- a/crates/ui/src/components.rs +++ b/crates/ui/src/components.rs @@ -2,11 +2,13 @@ mod facepile; mod follow_group; mod list_item; mod tab; +mod traffic_lights; pub use facepile::*; pub use follow_group::*; pub use list_item::*; pub use tab::*; +pub use traffic_lights::*; use std::marker::PhantomData; use std::rc::Rc; diff --git a/crates/ui/src/components/traffic_lights.rs b/crates/ui/src/components/traffic_lights.rs new file mode 100644 index 0000000000..128af9976f --- /dev/null +++ b/crates/ui/src/components/traffic_lights.rs @@ -0,0 +1,30 @@ +use gpui2::elements::div; +use gpui2::style::StyleHelpers; +use gpui2::{Element, Hsla, IntoElement, ParentElement, ViewContext}; + +use crate::theme; + +#[derive(Element)] +pub struct TrafficLights {} + +pub fn traffic_lights() -> TrafficLights { + TrafficLights {} +} + +impl TrafficLights { + fn render(&mut self, _: &mut V, cx: &mut ViewContext) -> impl IntoElement { + let theme = theme(cx); + + div() + .flex() + .items_center() + .gap_2() + .child(traffic_light(theme.lowest.negative.default.foreground)) + .child(traffic_light(theme.lowest.warning.default.foreground)) + .child(traffic_light(theme.lowest.positive.default.foreground)) + } +} + +fn traffic_light>(fill: C) -> div::Div { + div().w_3().h_3().rounded_full().fill(fill.into()) +} diff --git a/crates/ui/src/modules/title_bar.rs b/crates/ui/src/modules/title_bar.rs index 705d0d8866..82c5c0234b 100644 --- a/crates/ui/src/modules/title_bar.rs +++ b/crates/ui/src/modules/title_bar.rs @@ -5,7 +5,7 @@ use gpui2::style::StyleHelpers; use gpui2::{Element, IntoElement, ParentElement, ViewContext}; use crate::prelude::Shape; -use crate::{avatar, follow_group, icon_button, text_button, theme, tool_divider}; +use crate::{avatar, follow_group, icon_button, text_button, theme, tool_divider, traffic_lights}; #[derive(Element)] pub struct TitleBar { @@ -40,34 +40,7 @@ impl TitleBar { .h_full() .gap_4() .px_2() - // === Traffic Lights === // - .child( - div() - .flex() - .items_center() - .gap_2() - .child( - div() - .w_3() - .h_3() - .rounded_full() - .fill(theme.lowest.positive.default.foreground), - ) - .child( - div() - .w_3() - .h_3() - .rounded_full() - .fill(theme.lowest.warning.default.foreground), - ) - .child( - div() - .w_3() - .h_3() - .rounded_full() - .fill(theme.lowest.negative.default.foreground), - ), - ) + .child(traffic_lights()) // === Project Info === // .child( div()