Skip to content

Commit

Permalink
ui: More component previews, UI component cleanup (#25302)
Browse files Browse the repository at this point in the history
- Don't require ui component docs (this isn't really working)
- Add more component previews
- Update component preview style & navigation

Release Notes:

- N/A
  • Loading branch information
iamnbutler authored Feb 21, 2025
1 parent c9235ff commit 5397ca2
Show file tree
Hide file tree
Showing 52 changed files with 813 additions and 856 deletions.
4 changes: 2 additions & 2 deletions crates/collab_ui/src/collab_panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2458,8 +2458,8 @@ impl CollabPanel {
Avatar::new(contact.user.avatar_uri.clone())
.indicator::<AvatarAvailabilityIndicator>(if online {
Some(AvatarAvailabilityIndicator::new(match busy {
true => ui::Availability::Busy,
false => ui::Availability::Free,
true => ui::CollaboratorAvailability::Busy,
false => ui::CollaboratorAvailability::Free,
}))
} else {
None
Expand Down
15 changes: 8 additions & 7 deletions crates/component/src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,9 @@ pub enum ExampleLabelSide {
Left,
/// Right side
Right,
#[default]
/// Top side
Top,
#[default]
/// Bottom side
Bottom,
}
Expand All @@ -200,10 +200,10 @@ impl RenderOnce for ComponentExample {
ExampleLabelSide::Top => base.flex_col_reverse(),
};

base.gap_1()
base.gap_2()
.p_2()
.text_sm()
.text_color(cx.theme().colors().text)
.text_size(px(10.))
.text_color(cx.theme().colors().text_muted)
.when(self.grow, |this| this.flex_1())
.child(self.element)
.child(self.variant_name)
Expand Down Expand Up @@ -245,12 +245,13 @@ impl RenderOnce for ComponentExampleGroup {
.text_color(cx.theme().colors().text_muted)
.when(self.grow, |this| this.w_full().flex_1())
.when_some(self.title, |this, title| {
this.gap_4().pb_5().child(
this.gap_4().child(
div()
.flex()
.items_center()
.gap_3()
.child(div().h_px().w_4().bg(cx.theme().colors().border_variant))
.pb_1()
.child(div().h_px().w_4().bg(cx.theme().colors().border))
.child(
div()
.flex_none()
Expand All @@ -271,7 +272,7 @@ impl RenderOnce for ComponentExampleGroup {
.flex()
.items_start()
.w_full()
.gap_8()
.gap_6()
.children(self.examples)
.into_any_element(),
)
Expand Down
186 changes: 112 additions & 74 deletions crates/component_preview/src/component_preview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@
//! A view for exploring Zed components.
use component::{components, ComponentMetadata};
use gpui::{prelude::*, App, EventEmitter, FocusHandle, Focusable, Window};
use ui::prelude::*;
use gpui::{list, prelude::*, uniform_list, App, EventEmitter, FocusHandle, Focusable, Window};
use gpui::{ListState, ScrollHandle, UniformListScrollHandle};
use ui::{prelude::*, ListItem};

use workspace::{item::ItemEvent, Item, Workspace, WorkspaceId};

pub fn init(cx: &mut App) {
cx.observe_new(|workspace: &mut Workspace, _, _cx| {
workspace.register_action(
|workspace, _: &workspace::OpenComponentPreview, window, cx| {
let component_preview = cx.new(ComponentPreview::new);
let component_preview = cx.new(|cx| ComponentPreview::new(window, cx));
workspace.add_item_to_active_pane(
Box::new(component_preview),
None,
Expand All @@ -28,124 +29,161 @@ pub fn init(cx: &mut App) {

struct ComponentPreview {
focus_handle: FocusHandle,
_view_scroll_handle: ScrollHandle,
nav_scroll_handle: UniformListScrollHandle,
components: Vec<ComponentMetadata>,
component_list: ListState,
selected_index: usize,
}

impl ComponentPreview {
pub fn new(cx: &mut Context<Self>) -> Self {
pub fn new(_window: &mut Window, cx: &mut Context<Self>) -> Self {
let components = components().all_sorted();
let initial_length = components.len();

let component_list = ListState::new(initial_length, gpui::ListAlignment::Top, px(500.0), {
let this = cx.entity().downgrade();
move |ix, window: &mut Window, cx: &mut App| {
this.update(cx, |this, cx| {
this.render_preview(ix, window, cx).into_any_element()
})
.unwrap()
}
});

Self {
focus_handle: cx.focus_handle(),
_view_scroll_handle: ScrollHandle::new(),
nav_scroll_handle: UniformListScrollHandle::new(),
components,
component_list,
selected_index: 0,
}
}

fn render_sidebar(&self, _window: &Window, _cx: &Context<Self>) -> impl IntoElement {
let components = components().all_sorted();
let sorted_components = components.clone();
fn scroll_to_preview(&mut self, ix: usize, cx: &mut Context<Self>) {
self.component_list.scroll_to_reveal_item(ix);
self.selected_index = ix;
cx.notify();
}

v_flex()
.max_w_48()
.gap_px()
.p_1()
.children(
sorted_components
.into_iter()
.map(|component| self.render_sidebar_entry(&component, _cx)),
)
.child(
Label::new("These will be clickable once the layout is moved to a gpui::List.")
.color(Color::Muted)
.size(LabelSize::XSmall)
.italic(),
)
fn get_component(&self, ix: usize) -> ComponentMetadata {
self.components[ix].clone()
}

fn render_sidebar_entry(
&self,
component: &ComponentMetadata,
_cx: &Context<Self>,
ix: usize,
selected: bool,
cx: &Context<Self>,
) -> impl IntoElement {
h_flex()
.w_40()
.px_1p5()
.py_0p5()
.text_sm()
.child(component.name().clone())
let component = self.get_component(ix);

ListItem::new(ix)
.child(Label::new(component.name().clone()).color(Color::Default))
.selectable(true)
.toggle_state(selected)
.inset(true)
.on_click(cx.listener(move |this, _, _, cx| {
this.scroll_to_preview(ix, cx);
}))
}

fn render_preview(
&self,
component: &ComponentMetadata,
ix: usize,
window: &mut Window,
cx: &Context<Self>,
) -> impl IntoElement {
let component = self.get_component(ix);

let name = component.name();
let scope = component.scope();

let description = component.description();

v_flex()
.border_b_1()
.border_color(cx.theme().colors().border)
.w_full()
.gap_3()
.py_6()
.py_2()
.child(
v_flex()
.gap_1()
.border_1()
.border_color(cx.theme().colors().border)
.rounded_md()
.w_full()
.gap_4()
.py_4()
.px_6()
.flex_none()
.child(
h_flex()
v_flex()
.gap_1()
.text_2xl()
.child(div().child(name))
.when_some(scope, |this, scope| {
this.child(div().opacity(0.5).child(format!("({})", scope)))
.child(
h_flex()
.gap_1()
.text_xl()
.child(div().child(name))
.when_some(scope, |this, scope| {
this.child(div().opacity(0.5).child(format!("({})", scope)))
}),
)
.when_some(description, |this, description| {
this.child(
div()
.text_ui_sm(cx)
.text_color(cx.theme().colors().text_muted)
.max_w(px(600.0))
.child(description),
)
}),
)
.when_some(description, |this, description| {
this.child(
div()
.text_ui_sm(cx)
.text_color(cx.theme().colors().text_muted)
.max_w(px(600.0))
.child(description),
)
.when_some(component.preview(), |this, preview| {
this.child(preview(window, cx))
}),
)
.when_some(component.preview(), |this, preview| {
this.child(preview(window, cx))
})
.into_any_element()
}

fn render_previews(&self, window: &mut Window, cx: &Context<Self>) -> impl IntoElement {
v_flex()
.id("component-previews")
.size_full()
.overflow_y_scroll()
.p_4()
.gap_4()
.children(
components()
.all_previews_sorted()
.iter()
.map(|component| self.render_preview(component, window, cx)),
)
}
}

impl Render for ComponentPreview {
fn render(&mut self, window: &mut Window, cx: &mut Context<'_, Self>) -> impl IntoElement {
fn render(&mut self, _window: &mut Window, cx: &mut Context<'_, Self>) -> impl IntoElement {
h_flex()
.id("component-preview")
.key_context("ComponentPreview")
.items_start()
.overflow_hidden()
.size_full()
.max_h_full()
.track_focus(&self.focus_handle)
.px_2()
.bg(cx.theme().colors().editor_background)
.child(self.render_sidebar(window, cx))
.child(self.render_previews(window, cx))
.child(
uniform_list(
cx.entity().clone(),
"component-nav",
self.components.len(),
move |this, range, _window, cx| {
range
.map(|ix| this.render_sidebar_entry(ix, ix == this.selected_index, cx))
.collect()
},
)
.track_scroll(self.nav_scroll_handle.clone())
.pt_4()
.w(px(240.))
.h_full()
.flex_grow(),
)
.child(
v_flex()
.id("component-list")
.px_8()
.pt_4()
.size_full()
.child(
list(self.component_list.clone())
.flex_grow()
.with_sizing_behavior(gpui::ListSizingBehavior::Auto),
),
)
}
}

Expand Down Expand Up @@ -175,13 +213,13 @@ impl Item for ComponentPreview {
fn clone_on_split(
&self,
_workspace_id: Option<WorkspaceId>,
_window: &mut Window,
window: &mut Window,
cx: &mut Context<Self>,
) -> Option<gpui::Entity<Self>>
where
Self: Sized,
{
Some(cx.new(Self::new))
Some(cx.new(|cx| Self::new(window, cx)))
}

fn to_item_events(event: &Self::Event, mut f: impl FnMut(workspace::item::ItemEvent)) {
Expand Down
4 changes: 0 additions & 4 deletions crates/storybook/src/story_selector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ use ui::prelude::*;
pub enum ComponentStory {
ApplicationMenu,
AutoHeightEditor,
Avatar,
Button,
CollabNotification,
ContextMenu,
Cursor,
Expand Down Expand Up @@ -47,8 +45,6 @@ impl ComponentStory {
.new(|cx| title_bar::ApplicationMenuStory::new(window, cx))
.into(),
Self::AutoHeightEditor => AutoHeightEditorStory::new(window, cx).into(),
Self::Avatar => cx.new(|_| ui::AvatarStory).into(),
Self::Button => cx.new(|_| ui::ButtonStory).into(),
Self::CollabNotification => cx
.new(|_| collab_ui::notifications::CollabNotificationStory)
.into(),
Expand Down
49 changes: 0 additions & 49 deletions crates/ui/docs/building-ui.md

This file was deleted.

Loading

0 comments on commit 5397ca2

Please sign in to comment.