From 748ad5f05a6d8e02c6bdeea22f07f83a2e629ae8 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Tue, 19 Sep 2023 11:52:35 -0400 Subject: [PATCH] Make list_item `toggleable`, improve optional `left_icon` on list item Co-Authored-By: Julia <30666851+ForLoveOfCats@users.noreply.github.com> --- crates/storybook/src/prelude.rs | 6 +++ .../storybook/src/ui/component/list_item.rs | 30 ++++++++---- crates/storybook/src/ui/element/icon.rs | 46 +++++++++++++------ .../storybook/src/ui/module/project_panel.rs | 21 ++++++--- 4 files changed, 73 insertions(+), 30 deletions(-) diff --git a/crates/storybook/src/prelude.rs b/crates/storybook/src/prelude.rs index 8f013574062e57efb46284ab6d48383e0563ef4b..61dbb676e2d7d01a4843f2c5a84db7f32064c30b 100644 --- a/crates/storybook/src/prelude.rs +++ b/crates/storybook/src/prelude.rs @@ -47,3 +47,9 @@ pub enum SelectedState { PartiallySelected, Selected, } + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum ToggleState { + Toggled, + NotToggled, +} diff --git a/crates/storybook/src/ui/component/list_item.rs b/crates/storybook/src/ui/component/list_item.rs index 9e6a2463df73803e5fad83795306cf77410629e8..79631b943d75acb7a8001b29f8707fb28cc409c0 100644 --- a/crates/storybook/src/ui/component/list_item.rs +++ b/crates/storybook/src/ui/component/list_item.rs @@ -1,4 +1,4 @@ -use crate::prelude::InteractionState; +use crate::prelude::{InteractionState, ToggleState}; use crate::theme::theme; use crate::ui::{icon, IconAsset, Label}; use gpui2::geometry::rems; @@ -12,6 +12,7 @@ pub struct ListItem { left_icon: Option, indent_level: f32, state: InteractionState, + toggle: Option, } pub fn list_item(label: Label) -> ListItem { @@ -20,6 +21,7 @@ pub fn list_item(label: Label) -> ListItem { indent_level: 0.0, left_icon: None, state: InteractionState::default(), + toggle: None, } } @@ -28,10 +30,17 @@ impl ListItem { self.indent_level = indent_level; self } + + pub fn set_toggle(mut self, toggle: ToggleState) -> Self { + self.toggle = Some(toggle); + 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 @@ -40,7 +49,7 @@ impl ListItem { fn render(&mut self, _: &mut V, cx: &mut ViewContext) -> impl IntoElement { let theme = theme(cx); - let mut el = div() + div() .fill(theme.middle.base.default.background) .hover() .fill(theme.middle.base.hovered.background) @@ -53,13 +62,14 @@ impl ListItem { .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()) + .items_center() + .children(match self.toggle { + Some(ToggleState::NotToggled) => Some(icon(IconAsset::ChevronRight)), + Some(ToggleState::Toggled) => Some(icon(IconAsset::ChevronDown)), + None => None, + }) + .children(self.left_icon.map(|i| icon(i))) + .child(self.label.clone()), + ) } } diff --git a/crates/storybook/src/ui/element/icon.rs b/crates/storybook/src/ui/element/icon.rs index f0248ade64fa25e98ae38820c3e8859cb0b47890..5a9e8fb6cb7769f1e951d77a216d6d15646f8dad 100644 --- a/crates/storybook/src/ui/element/icon.rs +++ b/crates/storybook/src/ui/element/icon.rs @@ -1,11 +1,13 @@ -use std::borrow::Cow; - use crate::theme::theme; use gpui2::elements::svg; use gpui2::style::StyleHelpers; use gpui2::IntoElement; use gpui2::{Element, ViewContext}; +// Icon::Hash +// icon(IconAsset::Hash).color(IconColor::Warning) +// Icon::new(IconAsset::Hash).color(IconColor::Warning) + #[derive(Default, PartialEq, Copy, Clone)] pub enum IconAsset { Ai, @@ -18,19 +20,29 @@ pub enum IconAsset { File, Folder, FolderOpen, + ChevronDown, + ChevronUp, + ChevronLeft, + ChevronRight, } -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", +impl IconAsset { + pub fn path(self) -> &'static str { + match self { + 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::ChevronDown => "icons/chevron_down.svg", + IconAsset::ChevronUp => "icons/chevron_up.svg", + IconAsset::ChevronLeft => "icons/chevron_left.svg", + IconAsset::ChevronRight => "icons/chevron_right.svg", + IconAsset::File => "icons/file_icons/file.svg", + IconAsset::Folder => "icons/file_icons/folder.svg", + IconAsset::FolderOpen => "icons/file_icons/folder_open.svg", + } } } @@ -43,12 +55,18 @@ pub fn icon(asset: IconAsset) -> Icon { Icon { asset } } +// impl Icon { +// pub fn new(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)) + .path(self.asset.path()) .size_4() .fill(theme.lowest.base.default.foreground) } diff --git a/crates/storybook/src/ui/module/project_panel.rs b/crates/storybook/src/ui/module/project_panel.rs index 7cbaded2edd217ea0971c8daa6c455084ae8f4d3..347b453b18eeace5f56724a69a4fdddbbe132df8 100644 --- a/crates/storybook/src/ui/module/project_panel.rs +++ b/crates/storybook/src/ui/module/project_panel.rs @@ -1,5 +1,5 @@ use crate::{ - prelude::InteractionState, + prelude::{InteractionState, ToggleState}, theme::theme, ui::{input, label, list_item, IconAsset, LabelColor}, }; @@ -44,21 +44,30 @@ impl ProjectPanel { div().flex().flex_col().children( std::iter::repeat_with(|| { vec![ + list_item(label("sqlez").color(LabelColor::Modified)) + .left_icon(IconAsset::FolderOpen.into()) + .indent_level(0.0) + .set_toggle(ToggleState::NotToggled), list_item(label("storybook").color(LabelColor::Modified)) .left_icon(IconAsset::FolderOpen.into()) - .indent_level(0.0), + .indent_level(0.0) + .set_toggle(ToggleState::Toggled), list_item(label("docs").color(LabelColor::Default)) .left_icon(IconAsset::Folder.into()) - .indent_level(1.0), + .indent_level(1.0) + .set_toggle(ToggleState::Toggled), list_item(label("src").color(LabelColor::Modified)) .left_icon(IconAsset::FolderOpen.into()) - .indent_level(2.0), + .indent_level(2.0) + .set_toggle(ToggleState::Toggled), list_item(label("ui").color(LabelColor::Modified)) .left_icon(IconAsset::FolderOpen.into()) - .indent_level(3.0), + .indent_level(3.0) + .set_toggle(ToggleState::Toggled), list_item(label("component").color(LabelColor::Created)) .left_icon(IconAsset::FolderOpen.into()) - .indent_level(4.0), + .indent_level(4.0) + .set_toggle(ToggleState::Toggled), list_item(label("facepile.rs").color(LabelColor::Default)) .left_icon(IconAsset::File.into()) .indent_level(5.0),