From 8aa4fbea833328bb154bd7e8ebcf09baaa5dc84d Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Tue, 19 Sep 2023 00:25:46 -0400 Subject: [PATCH] Add icon, list_item, work on project panel --- crates/storybook/src/ui.rs | 27 ++++----- crates/storybook/src/ui/component.rs | 1 + .../storybook/src/ui/component/list_item.rs | 57 +++++++++++++++++++ crates/storybook/src/ui/element.rs | 1 + crates/storybook/src/ui/element/avatar.rs | 2 - crates/storybook/src/ui/element/icon.rs | 55 ++++++++++++++++++ crates/storybook/src/ui/element/label.rs | 2 +- .../storybook/src/ui/module/project_panel.rs | 40 ++++++++++--- 8 files changed, 160 insertions(+), 25 deletions(-) create mode 100644 crates/storybook/src/ui/component/list_item.rs create mode 100644 crates/storybook/src/ui/element/icon.rs diff --git a/crates/storybook/src/ui.rs b/crates/storybook/src/ui.rs index f2b020882d..3e431ca448 100644 --- a/crates/storybook/src/ui.rs +++ b/crates/storybook/src/ui.rs @@ -1,21 +1,22 @@ -mod component; mod element; -mod module; - -pub use component::facepile::*; -pub use component::follow_group::*; -pub use component::tab::*; - -pub use module::chat_panel::*; -pub use module::project_panel::*; -pub use module::status_bar::*; -pub use module::tab_bar::*; -pub use module::title_bar::*; - pub use element::avatar::*; +pub use element::icon::*; pub use element::icon_button::*; pub use element::indicator::*; pub use element::input::*; pub use element::label::*; pub use element::text_button::*; pub use element::tool_divider::*; + +mod component; +pub use component::facepile::*; +pub use component::follow_group::*; +pub use component::list_item::*; +pub use component::tab::*; + +mod module; +pub use module::chat_panel::*; +pub use module::project_panel::*; +pub use module::status_bar::*; +pub use module::tab_bar::*; +pub use module::title_bar::*; diff --git a/crates/storybook/src/ui/component.rs b/crates/storybook/src/ui/component.rs index 8e99b60483..49a1268863 100644 --- a/crates/storybook/src/ui/component.rs +++ b/crates/storybook/src/ui/component.rs @@ -1,3 +1,4 @@ pub(crate) mod facepile; pub(crate) mod follow_group; +pub(crate) mod list_item; pub(crate) mod tab; diff --git a/crates/storybook/src/ui/component/list_item.rs b/crates/storybook/src/ui/component/list_item.rs new file mode 100644 index 0000000000..099125b69c --- /dev/null +++ b/crates/storybook/src/ui/component/list_item.rs @@ -0,0 +1,57 @@ +use crate::prelude::InteractionState; +use crate::theme::theme; +use crate::ui::{icon, IconAsset, Label}; +use gpui2::geometry::rems; +use gpui2::style::StyleHelpers; +use gpui2::{elements::div, IntoElement}; +use gpui2::{Element, ParentElement, ViewContext}; + +#[derive(Element)] +pub struct ListItem { + label: Label, + left_icon: Option, + indent_level: f32, + state: InteractionState, +} + +pub fn list_item(label: Label) -> ListItem { + ListItem { + label, + indent_level: 0.0, + left_icon: None, + state: InteractionState::default(), + } +} + +impl ListItem { + pub fn indent_level(mut self, indent_level: f32) -> Self { + self.indent_level = indent_level; + self + } + pub fn left_icon(mut self, left_icon: Option) -> Self { + self.left_icon = left_icon; + self + } + pub fn state(mut self, state: InteractionState) -> Self { + self.state = state; + self + } + + fn render(&mut self, _: &mut V, cx: &mut ViewContext) -> impl IntoElement { + let theme = theme(cx); + + let mut el = div() + .h_7() + .px_2() + .ml(rems(0.75 * self.indent_level.clone())) + .flex() + .gap_2() + .items_center(); + + if self.left_icon.is_some() { + el = el.child(icon(self.left_icon.clone().unwrap())) + } + + el.child(self.label.clone()) + } +} diff --git a/crates/storybook/src/ui/element.rs b/crates/storybook/src/ui/element.rs index 145c4d1ecb..c5265e0ab4 100644 --- a/crates/storybook/src/ui/element.rs +++ b/crates/storybook/src/ui/element.rs @@ -1,4 +1,5 @@ pub(crate) mod avatar; +pub(crate) mod icon; pub(crate) mod icon_button; pub(crate) mod indicator; pub(crate) mod input; diff --git a/crates/storybook/src/ui/element/avatar.rs b/crates/storybook/src/ui/element/avatar.rs index cc25587c8d..83edc73deb 100644 --- a/crates/storybook/src/ui/element/avatar.rs +++ b/crates/storybook/src/ui/element/avatar.rs @@ -5,8 +5,6 @@ use gpui2::style::StyleHelpers; use gpui2::{ArcCow, IntoElement}; use gpui2::{Element, ViewContext}; -pub type UnknownString = ArcCow<'static, str>; - #[derive(Element, Clone)] pub struct Avatar { src: ArcCow<'static, str>, diff --git a/crates/storybook/src/ui/element/icon.rs b/crates/storybook/src/ui/element/icon.rs new file mode 100644 index 0000000000..f0248ade64 --- /dev/null +++ b/crates/storybook/src/ui/element/icon.rs @@ -0,0 +1,55 @@ +use std::borrow::Cow; + +use crate::theme::theme; +use gpui2::elements::svg; +use gpui2::style::StyleHelpers; +use gpui2::IntoElement; +use gpui2::{Element, ViewContext}; + +#[derive(Default, PartialEq, Copy, Clone)] +pub enum IconAsset { + Ai, + ArrowLeft, + ArrowRight, + #[default] + ArrowUpRight, + Bolt, + Hash, + File, + Folder, + FolderOpen, +} + +pub fn icon_asset(asset: IconAsset) -> impl Into> { + match asset { + IconAsset::Ai => "icons/ai.svg", + IconAsset::ArrowLeft => "icons/arrow_left.svg", + IconAsset::ArrowRight => "icons/arrow_right.svg", + IconAsset::ArrowUpRight => "icons/arrow_up_right.svg", + IconAsset::Bolt => "icons/bolt.svg", + IconAsset::Hash => "icons/hash.svg", + IconAsset::File => "icons/file_icons/file.svg", + IconAsset::Folder => "icons/file_icons/folder.svg", + IconAsset::FolderOpen => "icons/file_icons/folder_open.svg", + } +} + +#[derive(Element, Clone)] +pub struct Icon { + asset: IconAsset, +} + +pub fn icon(asset: IconAsset) -> Icon { + Icon { asset } +} + +impl Icon { + fn render(&mut self, _: &mut V, cx: &mut ViewContext) -> impl IntoElement { + let theme = theme(cx); + + svg() + .path(icon_asset(self.asset)) + .size_4() + .fill(theme.lowest.base.default.foreground) + } +} diff --git a/crates/storybook/src/ui/element/label.rs b/crates/storybook/src/ui/element/label.rs index 6ebe38b90b..bbbedd0b10 100644 --- a/crates/storybook/src/ui/element/label.rs +++ b/crates/storybook/src/ui/element/label.rs @@ -22,7 +22,7 @@ pub struct Label { pub fn label(label: &'static str) -> Label { Label { - label: "Label", + label, color: LabelColor::Default, } } diff --git a/crates/storybook/src/ui/module/project_panel.rs b/crates/storybook/src/ui/module/project_panel.rs index d954b9e6ce..7cbaded2ed 100644 --- a/crates/storybook/src/ui/module/project_panel.rs +++ b/crates/storybook/src/ui/module/project_panel.rs @@ -1,7 +1,7 @@ use crate::{ prelude::InteractionState, theme::theme, - ui::{input, label, LabelColor}, + ui::{input, label, list_item, IconAsset, LabelColor}, }; use gpui2::{ elements::{div, div::ScrollState}, @@ -29,7 +29,7 @@ impl ProjectPanel { let theme = theme(cx); div() - .w_64() + .w_56() .h_full() .flex() .flex_col() @@ -41,17 +41,39 @@ impl ProjectPanel { .flex_col() .overflow_y_scroll(self.scroll_state.clone()) .child( - div().py_2().flex().flex_col().children( + div().flex().flex_col().children( std::iter::repeat_with(|| { vec![ - label("File"), - label("Modified File").color(LabelColor::Modified), - label("Created File").color(LabelColor::Created), - label("Deleted File").color(LabelColor::Deleted), - label("Hidden File").color(LabelColor::Hidden), + list_item(label("storybook").color(LabelColor::Modified)) + .left_icon(IconAsset::FolderOpen.into()) + .indent_level(0.0), + list_item(label("docs").color(LabelColor::Default)) + .left_icon(IconAsset::Folder.into()) + .indent_level(1.0), + list_item(label("src").color(LabelColor::Modified)) + .left_icon(IconAsset::FolderOpen.into()) + .indent_level(2.0), + list_item(label("ui").color(LabelColor::Modified)) + .left_icon(IconAsset::FolderOpen.into()) + .indent_level(3.0), + list_item(label("component").color(LabelColor::Created)) + .left_icon(IconAsset::FolderOpen.into()) + .indent_level(4.0), + list_item(label("facepile.rs").color(LabelColor::Default)) + .left_icon(IconAsset::File.into()) + .indent_level(5.0), + list_item(label("follow_group.rs").color(LabelColor::Default)) + .left_icon(IconAsset::File.into()) + .indent_level(5.0), + list_item(label("list_item.rs").color(LabelColor::Created)) + .left_icon(IconAsset::File.into()) + .indent_level(5.0), + list_item(label("tab.rs").color(LabelColor::Default)) + .left_icon(IconAsset::File.into()) + .indent_level(5.0), ] }) - .take(60) + .take(10) .flatten(), ), ),