diff --git a/Cargo.lock b/Cargo.lock index 959ea95ee7..c0cdd5c7d6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3051,6 +3051,7 @@ dependencies = [ "languages", "notifications", "project", + "strum", "ui", "workspace", ] diff --git a/crates/component_preview/Cargo.toml b/crates/component_preview/Cargo.toml index 1242bde2e4..dfd621bfeb 100644 --- a/crates/component_preview/Cargo.toml +++ b/crates/component_preview/Cargo.toml @@ -16,11 +16,12 @@ default = [] [dependencies] client.workspace = true +collections.workspace = true component.workspace = true gpui.workspace = true languages.workspace = true +notifications.workspace = true project.workspace = true +strum.workspace = true ui.workspace = true workspace.workspace = true -notifications.workspace = true -collections.workspace = true diff --git a/crates/component_preview/src/component_preview.rs b/crates/component_preview/src/component_preview.rs index e913f80177..16694e79dd 100644 --- a/crates/component_preview/src/component_preview.rs +++ b/crates/component_preview/src/component_preview.rs @@ -18,6 +18,7 @@ use gpui::{ListState, ScrollHandle, UniformListScrollHandle}; use languages::LanguageRegistry; use notifications::status_toast::{StatusToast, ToastIcon}; use project::Project; +use strum::IntoEnumIterator; use ui::{prelude::*, Divider, ListItem, ListSubHeader}; use workspace::{item::ItemEvent, Item, Workspace, WorkspaceId}; @@ -62,6 +63,7 @@ pub fn init(app_state: Arc, cx: &mut App) { enum PreviewEntry { AllComponents, + AllIcons, Separator, Component(ComponentMetadata), SectionHeader(SharedString), @@ -83,6 +85,7 @@ impl From for PreviewEntry { enum PreviewPage { #[default] AllComponents, + AllIcons, Component(ComponentId), } @@ -196,6 +199,7 @@ impl ComponentPreview { // Always show all components first entries.push(PreviewEntry::AllComponents); + entries.push(PreviewEntry::AllIcons); entries.push(PreviewEntry::Separator); for scope in known_scopes.iter() { @@ -245,6 +249,20 @@ impl ComponentPreview { entry: &PreviewEntry, cx: &Context, ) -> impl IntoElement { + let custom_entry = |ix: usize, label: &str, page: PreviewPage| { + let selected = self.active_page == page.clone(); + + ListItem::new(ix) + .child(Label::new(label.to_string()).color(Color::Default)) + .selectable(true) + .toggle_state(selected) + .inset(true) + .on_click(cx.listener(move |this, _, _, cx| { + this.set_active_page(page.clone(), cx); + })) + .into_any_element() + }; + match entry { PreviewEntry::Component(component_metadata) => { let id = component_metadata.id(); @@ -264,18 +282,9 @@ impl ComponentPreview { .inset(true) .into_any_element(), PreviewEntry::AllComponents => { - let selected = self.active_page == PreviewPage::AllComponents; - - ListItem::new(ix) - .child(Label::new("All Components").color(Color::Default)) - .selectable(true) - .toggle_state(selected) - .inset(true) - .on_click(cx.listener(move |this, _, _, cx| { - this.set_active_page(PreviewPage::AllComponents, cx); - })) - .into_any_element() + custom_entry(ix, "All Components", PreviewPage::AllComponents) } + PreviewEntry::AllIcons => custom_entry(ix, "All Icons", PreviewPage::AllIcons), PreviewEntry::Separator => ListItem::new(ix) .child(h_flex().pt_3().child(Divider::horizontal_dashed())) .into_any_element(), @@ -303,6 +312,7 @@ impl ComponentPreview { .render_scope_header(ix, shared_string.clone(), window, cx) .into_any_element(), PreviewEntry::AllComponents => div().w_full().h_0().into_any_element(), + PreviewEntry::AllIcons => div().w_full().h_0().into_any_element(), PreviewEntry::Separator => div().w_full().h_0().into_any_element(), }) .unwrap() @@ -431,6 +441,34 @@ impl ComponentPreview { }); } } + + fn render_icon_preview(&self, icon: IconName, cx: &App) -> impl IntoElement { + v_flex() + .items_center() + .justify_center() + .flex_none() + .size_10() + .rounded_md() + .bg(cx.theme().colors().surface_background) + .child(Icon::new(icon)) + } + + fn render_all_icons(&self, cx: &App) -> impl IntoElement { + let all_icons = IconName::iter().collect::>(); + + div() + .p_8() + .flex() + .items_start() + .justify_start() + .flex_wrap() + .gap_1() + .children( + all_icons + .into_iter() + .map(|icon| self.render_icon_preview(icon, cx)), + ) + } } impl Render for ComponentPreview { @@ -484,6 +522,7 @@ impl Render for ComponentPreview { ) .child(match active_page { PreviewPage::AllComponents => self.render_all_components().into_any_element(), + PreviewPage::AllIcons => self.render_all_icons(cx).into_any_element(), PreviewPage::Component(id) => self .render_component_page(&id, window, cx) .into_any_element(), diff --git a/crates/ui/src/components/icon.rs b/crates/ui/src/components/icon.rs index fce2a8906a..aee5d88d7f 100644 --- a/crates/ui/src/components/icon.rs +++ b/crates/ui/src/components/icon.rs @@ -8,7 +8,7 @@ pub use decorated_icon::*; use gpui::{img, svg, AnimationElement, AnyElement, Hsla, IntoElement, Rems, Transformation}; pub use icon_decoration::*; use serde::{Deserialize, Serialize}; -use strum::{EnumIter, EnumString, IntoStaticStr}; +use strum::{Display, EnumIter, EnumString, IntoStaticStr}; use ui_macros::DerivePathStr; use crate::{prelude::*, Indicator}; @@ -109,6 +109,7 @@ impl IconSize { #[derive( Debug, + Display, PartialEq, Eq, Copy,